Spring - autowire a class that have a constructor [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Anyway to #Autowire a bean that requires constructor arguments?
In my controller I want to use #Autowired to inject a class using the method / constructor autowiring. for example using:
#Autowired
private InjectedClass injectedClass;
My problem is that the injected class injectedClass have a constructor, and I need to pass a variable to the constructor from the controller. How can I pass values to the constructors?

If you are using annotations you can apply #Autowired annotation to MyClass's constructor, which will auto wire beans you are passing to MyClass's special constructor. Consider following e.g.
public class MovieRecommender {
#Autowired
private MovieCatalog movieCatalog;
private CustomerPreferenceDao customerPreferenceDao;
#Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
this.customerPreferenceDao = customerPreferenceDao;
}
// ...
}

You can either mark private data members with #Resource(name = "x") annotation OR wire them using constructor injection in the application context XML.
Annotations and XML configuration can be mixed in Spring. It need not be all or nothing.
<bean id="myClass" class="foo.bar.MyClass">
<constructor-arg ref="yourArgRefHere"/>
</bean>

Related

Helper Class Spring Boot with Environment Values [duplicate]

This question already has answers here:
Accessing spring beans in static method
(7 answers)
Closed 2 years ago.
I would like to create a helper class, but it just failed..
The error : java.lang.NullPointerException: null
When i do this without making a static class (with autowired) it works without problem. But it's a helper class, i think the static class is the better thing.
Thanks for help
Helper.java
public final class UrlHelper {
#Autowired
private static Environment bean;
public static String method(String projet) {
return "titi"+ bean.getProperty("property.name");
}
}
And in my service, i use it like this :
String list = getRequest.getHTTPRequest(UrlHelper.method(projet));
In Spring, the #Autowired annotation allows you to resolve and inject beans into other beans. In your case, the UrlHelper class is not a bean and therefore, your Environment is not injected (stays null), hence the error. You have two options:
Make the UrlHelper a bean using #Component, #Service, etc. This will make your class non-static.
Keep the UrlHelper static, and pass the Environment as parameter. This, I believe, is the more correct approach. The Environment can be injected in the class calling the static method.

#autowired on method in Spring

I am learning Spring, and as far as I understand, when we use #annotation on a method which has a generic name (not a setter method), then the method's arguments are autowired.
public class MovieRecommender {
private MovieCatalog movieCatalog;
private CustomerPreferenceDao customerPreferenceDao;
#Autowired
public void prepare(MovieCatalog mC,
CustomerPreferenceDao cPD) {
this.movieCatalog = mC;
this.customerPreferenceDao = cPD;
}
// ...
}
So, here, the fields movieCatalog and customerPreferenceDao are autowired with the values of mC and cPD. What I fail to understand is how is this different from the same method without the "#autowired".
I understand #autowired when applied to a Field name, but not able to understand when the values are explicitly being passed to the method (either a setter or any other method), then what does Spring do special?
quite late answer, but here it is:
any method annotated with #Autowired is a config method. It is called on bean instantiation after field injection is done. The arguments of the method are injected into the method on calling.
The #autowired method you have provided does not need to be invoked from within your own code. It will be invoked by the Spring framework. Imagine a setter method in a class that is declared as #autowired. The setters parameter is provided by Spring. So before using the class object instance you do not have to write code to call the setter method, just like you don't need to provide the parameters of an #autowired constructor. There are lots of things you can do with autowired. Check out these two examples:
Calling #autowired method
Other uses of #autowired
One of the advantages of #autowired is that you do not have to instantiate the object, as Spring Framework will do that for you. But not only that, an #autowired object is managed by the Spring Framework, so you don't have to worry about handling of object instances, cause Spring does it for you. So it saves a lot of coding and unnecessary code that is often used to keep track of and manage the objects. Hopefully this was of some help.
#autowired on a method is used for setter-injection. it is not different from field injection besides that the beans is not that dependent on the spring-container, you could instantiate and wire it yourself as well.
one reason to use it is if you have circular dependencies.
another use of setter injection is that it allow re-injection of (a possibly optional) dependency at a later time (JMX).
public class MovieRecommender {
#Autowired
private MovieCatalog movieCatalog;
#Autowired
private CustomerPreferenceDao customerPreferenceDao;
}
Now you have no need for a prepare method!

#Autowired on arbitrary config methods

In the Spring reference guide it says that you can apply #Autowired annotation to methods with arbitrary names and/or multiple arguments as shown in the following code.
public class MovieRecommender {
private MovieCatalog movieCatalog;
private CustomerPreferenceDao customerPreferenceDao;
#Autowired
public void prepare(MovieCatalog movieCatalog,
CustomerPreferenceDao customerPreferenceDao) {
this.movieCatalog = movieCatalog;
this.customerPreferenceDao = customerPreferenceDao;
}
// ...
}
But the prepare() method is not going to be called by the Spring container because its not a setter method. How does #Autowired work in this situation?
It does not say you can use #Autowired for any method what it says is
Config methods may have an arbitrary name and any number of arguments; each of those arguments will be autowired with a matching bean in the Spring container.
<beans>
<bean id="myBean" class="..." init-method="prepare"/>
</beans>
The annotation #Autowired does not really care which method name you use. So, a method name like prepare works just as well as a method name along the lines of setMovieCatalog.
Furthermore, Spring handles multiple arguments in the method with #Autowired as well. This is typically used for constructor based injection but works out just fine for other methods (like your prepare-method).
So, what is required to make this work? Well, first of all the arguments to the method must be beans that are known by the Spring context. This means that the beans must be wired in the XML-context, annotated with a #Component, or a #Bean from a #Configuration class. Secondly, the class that holds the #Autowired method must also be a bean that is known to the Spring context.
If both of the above are fulfilled, the #Autowired simply works as expected. It can be used on any instance method no matter the name.
No matter whats the method name, #Autowired will try get auto wire during spring context initialization.

Autowired beans are null in CustomRepositoryImpl [duplicate]

This question already has answers here:
Why is my Spring #Autowired field null?
(21 answers)
Closed 9 years ago.
I'm just starting out with Spring Data and I'm trying to add a custom method to my repositories which requires another bean (which is preferably only created once (i.e. singleton))
The bean is declared in the root-context.xml like so
<bean class="org...CachedQueryTemplateFactory" />
With the proper namespace of course. I then try to inject this bean into a CustomRepositoryImpl using #Autowired
#Getter
#Setter
#Component
public class StudyRepositoryImpl implements StudyRepositoryCustom {
#PersistenceContext private EntityManager d_em;
#Autowired private QueryTemplateFactory queryTemplateFactory;
#Override
public List<Study> findStudies(
UUID indication,
List<UUID> variables,
List<UUID> treatments) {
QueryTemplate template = this.queryTemplateFactory.buildQueryTemplate("...");
...
}
}
However when running the code I get NullPointerException. When doing the wiring in a #Controller and then passing the reference to the repository it works, but I don't want to DI to happen in the controller. So why is the QueryTemplateFactory null in the StudyRepositoryImpl but not for the #Controller and how can I fix this?
Full code is available on GitHub https://github.com/joelkuiper/trialverse/tree/feature/injectQueryTemplate
Thanks in advance!
You probably just need to add either :
<context:component-scan base-package="packagewithservices"/>
OR
<context:annotation-config/>
Either of these register a AutowiredAnnotationBeanPostProcessor responsible for wiring in the #Autowired fields. The javadoc that I have linked to has more details.

how to Inject dependency in static method with spring? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to make spring inject value into a static field
I have below code
public class CustomerService {
private static CustomerDAO customerDao;
public static void getAllCustomers()
{
customerDao.getAllCustomers();// here i want
}
public static CustomerDAO getCustomerDao() {
return customerDao;
}
public static void setCustomerDao(CustomerDAO customerDao) {
CustomerService.customerDao = customerDao;
}
}
now i am calling CustomerService.getAllCustomers() from my Action object where getAllCustomers
is class level method. I want customerDao to be injected by spring in class CustomerService
so that when i call getAllCustomers dependency is available ?
I am using spring decalarative dependency injection
Your design collides head-on with the basic premise of Spring IoC. A static method is nothing more than a singleton method, and the core point of the IoC container is to manage your singletons. You must redesign to use instance methods and fields.
The only way static methods get into the picture is as factory methods, when some complex logic is needed to contribute a singleton to the container.
Do not declare the customerDao field static. Then wire the customer dao into your service class like:
<bean id="customerDao" class="com.example.CustomerDao">
<!-- whatever config you may need here -->
</bean>
<bean id="customerService" class="com.example.CustomerSerivce">
<property name="" ref="customerDao"/>
</bean>

Categories