Class bean in application context for Cacheable annotation - java

I'm using Spring 4.1.4 and Ehcache 2.9 and caching using the #Cacheable annotation.
I've noticed that every public class that has a method with this annotation must be referenced in
applicationContext.xml
as follows
<bean class="com.example.web.Test"/>
this forces me to add every public class that i want to cache into the applicationContext.
Is there a way to overcome this?
Thanks

Of course #Cacheable works only for spring beans.
There are many ways to instantiate a spring bean, explicite xml configuration <bean class="..."/> is only one. An other way is to enable the component scan and annotate the class with #Component or #Service (or some other) annotations.

Related

Spring - Are annotations like #Component BeanPostProcessors

I read that Spring annotations like #Autowired, #Transactional & #PostConstruct are a form of / use BeanPostProcessors. So from what I understand about BeanPostProcessors, they are used to manage the lifecycle of a Spring Bean. Meaning you can specify any code which should be run before or after the intialization of a bean.
Now annotations like #Component or #Bean specify to Spring that it should create beans of this type. For example,
#Component
public Class Foo {
}
will tell spring to create a Bean of type "Foo" and then Spring will manage it's lifecycle. So does that make #Component and #Bean BeanPostProcessors?
I read that Spring annotations like #Autowired, #Transactional & #PostConstruct are a form of / use BeanPostProcessors.
Neither, it's actually the opposite. It is BeanPostProcessors that look for the annotations and react accordingly.
AutowiredAnnotationBeanPostProcessor - BeanPostProcessor implementation that autowires annotated fields, setter methods, and arbitrary config methods. Such members to be injected are detected through annotations: by default, Spring's #Autowired and #Value annotations.
Also supports JSR-330's #Inject annotation, if available, as a direct alternative to Spring's own #Autowired.
CommonAnnotationBeanPostProcessor - BeanPostProcessor implementation that supports common Java annotations out of the box, in particular the JSR-250 annotations in the javax.annotation package. These common Java annotations are supported in many Java EE 5 technologies (e.g. JSF 1.2), as well as in Java 6's JAX-WS.
This post-processor includes support for the PostConstruct and PreDestroy annotations - as init annotation and destroy annotation, respectively - through inheriting from InitDestroyAnnotationBeanPostProcessor with pre-configured annotation types.
Note that #Transactional is not handled by a BeanPostProcessor.
Now annotations like #Component or #Bean specify to Spring that it should create beans of this type. [...] So does that make #Component and #Bean BeanPostProcessors?
No.
#Component is an annotation that the component-scanning framework looks for to find beans to register. The component-scanning framework also looks for annotations that are themselves annotated with #Component, such as the #Configuration, #Controller, #Service, and #Repositiory annotations.
The #Bean annotation is then handled by a BeanDefinitionRegistryPostProcessor (not a BeanPostProcessor).
ConfigurationClassPostProcessor - BeanFactoryPostProcessor used for bootstrapping processing of #Configuration classes.
This post processor is priority-ordered as it is important that any Bean methods declared in #Configuration classes have their corresponding bean definitions registered before any other BeanFactoryPostProcessor executes.
No! They are different.
BeanPostProcessor is used to perform some operations before and after creating a bean,this allows us to add some code before and after creating the bean.
BeanPostProcessor class has two methods.
postProcessBeforeInitialization : It's used to make sure required actions are taken before initialization. e.g. you want to load certain property file/read data from the remote source/service.
postProcessAfterInitialization : It takes care of tasks that you want to do after initialization before bean reference is given to application.
Refer to : spring-doc-beans-customizing-using-BeanPostProcessor
interface for details.
#Component : It's the most generic Spring annotation.
A Java class decorated with #Component is found during classpath scanning and registered in the context as a Spring bean.
Refer to : spring-doc-component-annotation for details.

Spring: Xml based Autowiring a list of beans by interface type

With Spring it is possible to inject a list of beans by the interface class like:
#Component
public class Service {
#Autowire
private List<InterfaceType> implementingBeans;
...
}
All defined beans that implement this interface will be present in this List.
The annotation based approach is not possible for me, as the Service class is in a module that must not have spring dependencies.
I need to use this mechanism from outside via xml configuration.
<bean id="service" class="...Service">
<property name="implementingBeans">
??? tell spring to create a list bean that resolves all beans of the interfaceType.
</property>
</bean>
Does anyone know how to solve this?
EDIT: Additionally, there are more than one spring applications that use this service. So the best solution would be to handle this szenario completely via xml configuration. I can then copy the xml parts to all spriong applications that need this.
I want to avoid having a kind of initializer bean that gets the service injected and must then be copied to all spring applications.
Kind regards.
An XML-only solution would simply have you declare a <bean> of the "external" type and provide an autowire value of "byType".
Controls whether bean properties are "autowired". This is an
automagical process in which bean references don't need to be coded
explicitly in the XML bean definition file, but rather the Spring
container works out dependencies.
[...]
"byType" Autowiring if there is exactly one bean of the property type in the container. If there is more than one, a fatal error is
raised, and you cannot use byType autowiring for that bean. If there
is none, nothing special happens.
The explanation is a little confusing in that we expect multiple InterfaceType beans, but the actual field is of type List and Spring will be able to dynamically instantiate one and add all the InterfaceType beans to it, then inject it.
Your XML would simply look like
<bean id="service" class="...Service" autowire="byType">
</bean>
My original suggested solution made use of SpEL.
In the module that does have Spring dependencies, create a DTO
#Component(value = "beanDTO")
public class BeanDTO {
#Autowire
private List<InterfaceType> implementingBeans;
public List<InterfaceType> getImplementingBeans() {
return implementingBeans;
}
}
and then use SpEL to retrieve the value of implementingBeans from the beanDTO bean.
<bean id="service" depends-on="beanDTO" class="...Service">
<property name="implementingBeans" value="{beanDTO.implementingBeans}" />
</bean>
Spring will create the BeanTDO bean, inject all the beans that are of type InterfaceType. It will then create the service bean and set its property from beanDTO's implementingBeans property.
Following comments on question:
In an effort to be more JSR 330 compliant, Spring has introduced support for Java EE's javax.inject package. You can now annotate your injection targets with #javax.inject.Inject instead of #Autowired. Similarly, you can use #Named instead of #Component. The documentation has more details.

Implementing Dependency Injection using Custom Annotation

I am working on a core java framework. I don't want to create instances directly inside the class which is why I want to use dependency injection.
I am thinking of declaring my custom annotations on the fields to be instantiated. And having a call back function which would create an instance and inject it into the field.
I had tried to create a custom annotation. But looks like there's no direct way to get a callback on the declared annotation. So, I was trying to scan the classes for that. But I ended up with this problem
Java Scanning Class for Annotation using Google Reflections
Please let me know if this is the right way of achieving this.
Since your question is tagged 'Spring', you can use Spring Framework's bean annotations (#Component / #Service / #Repository / ...), classpath scanning and #Autowired.
For example:
Setup classpath scanning on your spring config xml:
<context:component-scan base-package="com.mycompany.myapp" />
Create your bean to be scanned. Spring container will automatically create a singleton instance of this bean using default constructor:
#Repository
public class FooDAO {
...
}
Inject reference to above DAO instance using DI + autowiring
#Service
public class FooService {
#Autowired private FooDAO fooDAO;
...
}

Some doubts about the use of **#Autowired** annotation and interface declaration in Spring Framework

I am quite new in Spring framework and I have some questions about the use of #Autowired annotation and interface declaration.
Referring to this example:
http://viralpatel.net/blogs/spring3-mvc-hibernate-maven-tutorial-eclipse-example/
I know that #Autowired annotation can be used to automatically link a bean on a property.
In the previous example I have the following situation:
I have a ContactDAO interface and it's implementation class named ContactDAOImpl
Next in the class ContactServiceImpl there is this variable annoted using #Autowired:
#Autowired
private ContactDAO contactDAO;
My first doubt is related to the fact that ContactDAO is an interface so what am I wiring? The concrete type: ContactDAOImpl ? If yes, is the Spring Framework that do it?
The second doubt is related to the fact that in the spring-servlet.xml configuration file there is not a bean definizion for the ContactDAO orf ContactAOImpl class...why? Is it because ContactDAOImpl class is annoted using #Repository annotation?
Thanks
Andrea
My first doubt is related to the fact that ContactDAO is an interface
so what am I wiring? The concrete type: ContactDAOImpl ? If yes, is
the Spring Framework that do it?
Spring will autowire an implementation of the interface for you, as long as there's only one matching implementation. There's also a way to match a single implementation from multiple candidates to your autowiring by using #Qualifier with #Autowired and naming the implementation.
The second doubt is related to the fact that in the spring-servlet.xml
configuration file there is not a bean definizion for the ContactDAO
orf ContactAOImpl class...why? Is it because ContactDAOImpl class is
annoted using #Repository annotation?
If you're using annotations (#Component, #Repository, #Service, #Controller) in your implementations for configuration, you don't need to explicitly define the bean in the xml (although you can do that also).
Edit: this old answer of mine might shed some more light about using annotations in Spring.
The answers to your two questions are Yes, and Yes.
In fact, you might not have an instance of ContactDAOImpl autowired in the service, but an instance of a proxy, which deletages to an instance of ContactDAOImpl. The proxy will typically handle transactions, translate exceptions, etc.
And the #Repository annotation is an alternative (simpler) way to declare a Spring bean. It works only if you have an element in the Spring xml file telling it to discover annotated beans.
Spring will autoscan all your classes and find all annotated classes and register them, this in your spring config will tell it to do that:
<context:component-scan base-package="my.base.package" />
Therefore you do not need to declare your #Repository in your configuration file.
Onto the first part of your question, this is the unpinning of the IOC pattern; your Service class is only aware of the interface of the DAO, this means that it is not dependent on the implementation.
During scanning Spring will find all of your annotated classes and when you ask for an #Autowired then it will attempt to find a class that your have annotated that is an implentor of the interface you have asked to have Autowired.
Have a look at the Spring documentation on Annotation Configuration.

Registering beans from a Configuration-annotated class

I have a class annotated with #Configuration (let's call it StubConfiguration) which has a single method that is annotated with #Bean. This method returns a BeanFactoryPostProcessor implementation which is responsible for registering some beans. However, Spring is unable to resolve the beans this factory registers at runtime.
My assumption is that StubConfiguration is picked up by Spring's component scanning, the BeanFactoryPostProcessor is registered and then its postProcessBeanFactory() method is invoked, subsequently registering the beans I need.
Am I thinking about this incorrectly? How can I go about registering the beans that I need with my ApplicationContext using this post processing?
If you're also using an XML app context to declare beans, you can tell Spring to do a component scan and treat #Stub as a Spring component annotation.
<context:component-scan base-package="your.base.package">
<context:include-filter type="annotation" expression="your.stub.package.Stub"/>
</context:component-scan>
If you're only using an annotation config app context, check out this answer for a way to do it without XML.
What about making your #Stub annotation extend the #Component annotation? Like the #Service or #Repository.
You will have your beans scanned with the regular Spring context scanning, you can keep your custom annotation and you won't need to register manually your beans.
Example from #Service:
{#Target({ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Documented
#Component
public #interface Service {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* #return the suggested component name, if any
*/
String value() default "";
}}

Categories

Resources