#Component annotation still needed on beans that has a FactoryBean? - spring

Suppose I have
public class MyBean
and
#Component
public class MyBeanFactory implements FactoryBean<MyBean>
I want to inject MyBean using #Autowired annotation. In that case, do I still need to annotate MyBean with #Component? I thought I should be able to but if I do, spring seems to not use MyBeanFactory to create the bean. If I don't, I can get the get the bean created by factory.

Your factory bean is used to create a bean of type MyBean instantiated according to whatever code you put in your factory bean implementation.
Putting #Component on MyBean will just create a new instance of MyBean and then create a bean from that instance.
If you are using a factory bean to create MyBean then there is no need to put #Component on MyBean.
What are you actually trying to achieve anyway ?

Related

How to Fix Could not autowire. No beans of error in Spring Boot

How can I solve this error. I'm New to Spring-boot
As I can see the spring unable to find the bean UserDetailsServiceImpl, there might be couple of reason for it.
First, you might forgot to put #Service annotation on top of the class UserDetailsServiceImpl. Also, as the context is about Spring security so make sure that this class UserDetailsServiceImpl must implement the interface UserDetailsService
#Service
public class UserDetailsServiceImpl implements UserDetailsService {
}
Second, spring might be unable to scan this folder. So make sure spring IOC must scan this package while intialization and configure the bean.
In order to #Autowired a bean instance, a class should be decorated with Spring stereotype annotation like #Component, #Service, #Repository, #Controller or #Indexed. Just by decorating the class with one of these role annotations, you can use #Autowired to bind with the instance.
Otherwise, if none of these annotations are used, your class instances, you have to manually registered to the BeanFactory like this;
#Configuration
public class SomeClass {
...
#Bean
public UserDetailsServiceImpl userDetailsService() {
return new UserDetailsServiceImpl()
}
}
This answer just talk about your specific question, but you get to find out why #Configuration is used in preceeding example. Define scopes for bindings, singleton (one instance for the application) is the default scope in Spring, you should define scopes for beans if they should be in different scope on your requirements.

Spring function based injection

Is there any way to inject a spring bean using #Autowired and instead of using a qualifier, using a custom annotation which resolves the bean based on a function and an argument?
For example
#Autowired
#FunctionQualifier(method=fetchCorrectBean)
private MyService myService;
The fetchCorrectBean is a function which will fetch the bean from the application context and inject it.

Wiring beans into TestNG listener that implements IInvokedMethodListener

I have a TestNG listener that implements IInvokedMethodListener. I would like to wire in a Spring bean inside this listener and use it. Unfortunately, this class is instantiated by TestNG and so Spring cannot wire anything in that is annotated using #Autowired. I tried implementing ApplicationContextAware, but that doesn't work either.
Is there a way to wire Spring beans into classes that implement IInvokedMethodListener?
ApplicationContextAware only works for Spring Beans. You can use #Configurable, but that requires AspectJ.
Here's a simple hack that should work: Add a static member to your listener class and inject it via a non-static setter.
public class MyMethodListener implements IInvokedMethodListener {
private static MyBean myBean;
#Autowired
public void setMyBean(MyBean myBean) {
MyMethodListener.myBean = myBean;
}
}
Include a bean of the required type in your application context.
The listener instantiated by TestNG will not be the same instance as the one from the Spring context, but it will have the static member set, provided that context creation has finished before TestNG instantiates the listener.
I had the same problem recently, it is basically Listeners are not maintained by spring. So I did some googling around this concept like "Injecting beans into classes not managed by spring", I got https://dzone.com/articles/autowiring-spring-beans-into-classes-not-managed-by-spring link which explains exactly the same problem and the solution. It worked for me.

Prevent autowiring by type for certain beans in Spring

In my spring context I am creating a service bean and a proxy for this service bean (explicitly). Both implement the same interface.
Can I ensure that autowiring cannot inject the target bean?
I would like to be able to use the target service with the #Resource or #Qualifier annotations, but when autowiring it should always be the proxy.
Any ideas?
Use the Primary annotation. It will indicate which bean should be use preferably when autowiring.
Hope this helps :)
You can put #Primary annotation in your proxy service like bellow:
#Primary
#Repository
public class ProxyOfSomeService implements SomeService
And after that when you use, #Autowired annotation on SomeService field, the ProxyOfSomeService will be injected by deafault.
But when you need the real service you can have it like bellow:
#Autowired
#Resource(name="someRealService")
private SomeService someService;
I think this serves your need, thanks!

Injecting a bean with #Autowired that implements ApplicationListener does not work?

I have a service bean (annotated with #Service) which implements the ApplicationListener inteface for T type of event objects that extend the ApplicationEvent abstract Class. There is a pretty simple and clear example of this in the Spring docs here
However when i attempt to inject this bean into other ones using #Autowired i get is:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
matching bean of type [...] found for dependency: expected at least 1
bean which qualifies as autowire candidate for this dependency.
Dependency annotation
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
If i try to use something like #Resource then i get a class cast exception (attempting to inject a resource of one type but getting a Proxy).
If i try to use something like #Resource then i get a class cast
exception (attempting to inject a resource of one type but getting a
Proxy).
This sounds like you are trying to reference it by class, whereas it is wired as an interface-based JDK proxy.
If you have this class:
#Service
public class FooServiceImpl implements FooService{}
wire it as:
#Autowired
private FooService fooService;
not as:
#Autowired
private FooServiceImpl fooService;
Reference:
AOP Proxying Mechanisms

Resources