I have an Interface with Component
annotation and some classes that implemented it as follows:
@Component
public interface A {
}
public class B implements A {
}
public class C implements A {
}
Also, I have a class with an Autowired
variable like this:
public class Collector {
@Autowired
private Collection<A> objects;
public Collection<A> getObjects() {
return objects;
}
}
My context file consists of these definitions:
<context:component-scan base-package="org.iust.ce.me"></context:component-scan>
<bean id="objectCollector" class="org.iust.ce.me.Collector" autowire="byType"/>
<bean id="b" class="org.iust.ce.me.B"></bean>
<bean id="c" class="org.iust.ce.me.C"></bean>
And in the main class, I have some codes as follows:
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
B b = (B) context.getBean("b");
C c = (C) context.getBean("c");
Collector objectCollector = (Collector) context.getBean("objectCollector");
for (A object : objectCollector.getObjects()) {
System.out.println(object);
}
Output:
org.iust.ce.me.B@1142196
org.iust.ce.me.C@a9255c
These codes work well, but for some reasons I’m not willing to use xml context file. Besides it, I prefer to create the objects with the new
operator rather than using the getBean()
method. Nevertheless, since the AutoWiring
is really good idea in programming, I don’t want to lose it.
Now I have two questions!!
how can I AutoWire
classes that implements the A
Interface without using the xml context file?
Is it possible at all?
when I change the scope
of a bean from singlton
to
prototype
as follows:
<bean id="b" class="org.iust.ce.me.B" scope="prototype"></bean>
and instantiate several beans of it, only the bean which was instantiated during creating context
, is injected
into AutoWired
variable. Why?
Any help will be appreciated.
Not sure the version of Spring you are using. But currently you can use @Configuration
to replace .xml. Take a look at @Configuration
Below is the code in documentation
@Configuration
public class ServiceConfig {
private @Autowired RepositoryConfig repositoryConfig;
public @Bean TransferService transferService() {
return new TransferServiceImpl(repositoryConfig.accountRepository());
}
}
@Configuration
public interface RepositoryConfig {
@Bean AccountRepository accountRepository();
}
@Configuration
public class DefaultRepositoryConfig implements RepositoryConfig {
public @Bean AccountRepository accountRepository() {
return new JdbcAccountRepository(...);
}
}
@Configuration
@Import({ServiceConfig.class, DefaultRepositoryConfig.class}) // import the concrete config!
public class SystemTestConfig {
public @Bean DataSource dataSource() { /* return DataSource */ }
}
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SystemTestConfig.class);
TransferService transferService = ctx.getBean(TransferService.class);
transferService.transfer(100.00, "A123", "C456");
}
Provided the classes to be managed have been correctly annotated, Spring can scan the application's files to get the information it needs without any xml or java configuration files at all.
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.scan("com.something.something.etc");
context.refresh();
...context.getBean("name_of_bean");
Note AnnotationConfigApplicationContext
is instantiated without any arguments. context.scan("...");
takes a string that tells Spring where to look. i.e. packages
com.something.something.etc.one com.comething.something.etc.twowill be scanned, and classes within those packages annotated with
@Component
, @Autowired
, etc. will be instatiated and injected where needed.
This approach doesn't seem to be as well documented.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With