Injecting collection of beans vs using ApplicationContextAware to getBeansOfType - spring

If I do
#Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
myBeans = applicationContext.getBeansOfType(MyBean.class).values();
}
does that have exactly the same effect as putting this in my constructor?
#Inject
public MyClass(Collection<MyBean> myBeans) {
this.myBeans = myBeans;
}

in commot case yes (without #Lazy ,#Value , required...), they are do the same effect.
In a Spring application, the two annotations works the same way as Spring has decided to support some JSR-299 annotations in addition to their own.
But there are some annotation that doen't hendled by #Inject like - laze , required as it's part of spring but not part of jsr.
Looks like if - all that you get by #Inject for Collection myBeans you get in spring also , but it's not true for all getted by spring also loaded by #inject
here is blog about comparison #AUTOWIRED AND #INJECT SPRING INJECTION WITH #RESOURCE, #AUTOWIRED AND #INJECT

Related

In a Spring Boot application is a Bean Factory/Application context ever explicitly used?

I am fairly new to Spring Boot and it is my sense from looking at sample applications that if a Bean Factory is ever used, it is used "under the covers" by Spring Boot. Or are there cases when using Spring Boot that you would in fact want to explicitly obtain a bean using the Bean Factory?
Every once in a while, I access Spring ApplicationContext from a bean that I initialize with new (basically a non-Spring managed bean) as follows:
#Component
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext context;
public static ApplicationContext getApplicationContext() {
return context;
}
#Override
public void setApplicationContext(ApplicationContext ac)
throws BeansException {
context = ac;
}
}
and in wherever I need it:
SomeBean someBean = ApplicationContextProvider.getApplicationContext().getBean("testBean", TestBean.class);
This is because:
I have to access a singleton (say, a #Service or a #Repository) from a bean I initialize (new) and I cannot make my bean Spring managed for that case. (so no #Autowired).
I don't want to introduce #Configurable to the project because it brings in AspectJ, which might be overkill to introduce for this simple case.

ClassBridge with DAO class injected

I have a Hibernate Search ClassBridge where I want to use #Inject to inject a Spring 4.1 managed DAO/Service class. I have annotated the ClassBridge with #Configurable. I noticed that Spring 4.2 adds some additional lifecycle methods that might do the trick, but I'm on Spring 4.1
The goal of this is to store a custom field into the index document based on a query result.
However, since the DAO, depends on the SessionFactory getting initialized, it doesn't get injected because it doesn't exist yet when the #Configurable bean gets processed.
Any suggestions on how to achieve this?
You might try to create a custom field bridge provider, which could get hold of the Spring application context through some static method. When provideFieldBridge() is called you may return a Spring-ified instance of that from the application context, assuming the timing is better and the DAO bean is available by then.
Not sure whether it'd fly, but it may be worth trying.
Hibernate Search 5.8.0 includes support for bean injection. You can see the issue https://hibernate.atlassian.net/browse/HSEARCH-1316.
However I couldn't make it work in my application and I had implemented a workaround.
I have created an application context provider to obtain the Spring application context.
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext context;
public static ApplicationContext getApplicationContext() {
return context;
}
#Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
ApplicationContextProvider.context = context;
}
}
I have added it to the configuration class.
#Configuration
public class RootConfig {
#Bean
public ApplicationContextProvider applicationContextProvider() {
return new ApplicationContextProvider();
}
}
Finally I have used it in a bridge to retrieve the spring beans.
public class AttachmentTikaBridge extends TikaBridge {
#Override
public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
// get service bean from the application context provider (to be replaced when HS bridges support beans injection)
ApplicationContext applicationContext = ApplicationContextProvider.getApplicationContext();
ExampleService exampleService = applicationContext.getBean(ExampleService .class);
// use exampleService ...
super.set(name, content, document, luceneOptions);
}
}
I think this workaround it's quite simple in comparision with other solutions and it doesn't have any big side effect except the bean injection happens in runtime.

Spring 4 Using #Lazy and #Resource annotations together

I would like to lazy load a resource within a lazy loaded configuration class. it seems that it is not currently possible with Spring 4.1.
#Configuration
#Lazy
public class ModificationConfiguration {
#Resource(name="modProps")
#Lazy
Map<String, String> props;
#Bean
Map<String, String> modProps(){
...
}
}
from the Spring documentation
In addition to its role for component initialization, the #Lazy annotation may also be placed on
injection points marked with #Autowired or #Inject. In this context, it leads to the injection
of a lazy-resolution proxy.
It seems natural to also want this available with #Resource as I can't use #Autowired on a Map<String, String>. Without the #Lazy being available on #Resource the modProps() bean is created straight away.
Is there a technical reason why it is not currently possible to do this?

Regarding Spring's #Autowired and Wicket's #SpringBean

I am currently looking into integrating Mockito and JUnit into my Wicket/Spring/Hibernate project and have found a tutorial on how to do this using annotations.
Trouble is I am unfamiliar with #Autowired and after a look on google I am finding it hard to see the difference between this annotation and the #SpringBean annotation.
Are they one in the same or is there a difference I should be aware of ?
My code to offer some context to this question:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath:applicationContext.xml"})
#TransactionConfiguration(transactionManager = "txManager", defaultRollback = false)
public class TestHome
{
private WicketTester tester;
#Autowired
private ApplicationContext ctx;
#Autowired
private WebApplication webApplication;
#Before
public void setUp() {
tester = new WicketTester(webApplication);
}
#Test
#Transactional
#Rollback(true)
public void testRenderHomePage() {
tester.startPage(Home.class);
tester.assertRenderedPage(Home.class);
tester.assertComponent("home", Home.class);
}
}
If you use Wicket SpringComponentInjector, it uses its own injection. The #Autowired annotation is a Springframework annotation, but Wicket SpringComponentInjector ignores that. So the Wicket annotation is #SpringBean that marks a field to be autowired (injected) by Spring bean or component that has to exist in Spring context.
In you code snippet you use the SpringJUnit4ClassRunner runner, so your fields are injected by Spring, so it is correct.
See an example, how to use SpringComponentInjector at How can I get a Spring bean injected in my custom Wicket model class?

#ManagedProperty equivalent in Spring

I am using Spring for my DI.
Is there an equivalent of #ManagedProperty? I want to inject the value from one view scoped bean into another one on the next page.
e.g
#Component
#Scope("view")
public class Page1Bean(){
private String value;
}
#Component
#Scope("view")
public class Page2Bean(){
#ManagedProperty(value = #{page1Bean}") //doesnt work in Spring
private Page1Bean bean;
}
#Resource or #Autowired should work. #Resource is the Java EE implementation, #Autowired is the spring specific annotation. I can't find the reference now, but it seems like I read once to prefer #Resource over #Autowired.
here's a blog post I found that talks about #Inject vs. #Resource vs. #Autowired
http://blogs.sourceallies.com/2011/08/spring-injection-with-resource-and-autowired/#more-2350

Resources