Spring Bean implements interface - spring

public interface Service {
public void doSomething();
}
#Service
public class MyService implements service{
#Transactional
public void doSomething(){
}
}
#Controller
public class MyController {
#Autowired
private MyService service;
}
In above scenario autowiring fails with exception "illegalArgumentException : argument type mismatch". When I remove implements service from MyService everything works fine.
I have searched and found that place <aop:aspectj-autoproxy proxy-target-class="true"/> in applicationContext.xml for successful autowiring and it worked.
I have also found that spring uses JDK proxy when #Transactional is used.
I have some confusions,
How #Transactional relates to Proxying
Why spring uses JDK Proxy for the beans which implements interfaces.
Why I need to place <aop:aspectj-autoproxy proxy-target-class="true"/> in applicationContext.xml
Can anyone please explain ? or refer me any article or blog

Proxying is how Spring implements declarative transaction management. Spring reference is the best place for all your questions on this.
The most important concepts to grasp with regard to the Spring Framework's declarative transaction support are that this support is enabled via AOP proxies, and that the transactional advice is driven by metadata (currently XML- or annotation-based). The combination of AOP with transactional metadata yields an AOP proxy that uses a TransactionInterceptor in conjunction with an appropriate PlatformTransactionManager implementation to drive transactions around method invocations.
and on <aop:aspectj-autoproxy proxy-target-class="true"/>
The proxy-target-class attribute on the
element controls what type of transactional proxies are created for
classes annotated with the #Transactional annotation. If
proxy-target-class attribute is set to true, class-based proxies are
created. If proxy-target-class is false or if the attribute is
omitted, standard JDK interface-based proxies are created. (See
Section 8.6, “Proxying mechanisms” for a discussion of the different
proxy types.)

Related

Spring #configure annotation usage without bean definitions

I have some experience with spring dependency injection and transaction management but I am new to spring security. When i was reading an article related to spring security, I found that #Configuration annotation is used in an example but there were no bean definitions to be found.
According to my understanding, #Configuration annotation is used in classes which contain bean definitions. I need to know that what does the #Configuration annotation do in this example.
#Configuration
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {
#Autowired
DataSource dataSource;
... // web stuff here
#Override
public configure(AuthenticationManagerBuilder builder) {
builder.jdbcAuthentication().dataSource(dataSource).withUser("dave")
.password("secret").roles("USER");
}
}
Thank you
It's not mandatory to have Bean definitions in Spring managed classes.
In this case #Configuration (which wraps #Component) is used to indicate to Spring that this class should be instantiated and all it's dependencies should be injected - in this case that's DataSource and AuthenticationManagerBuilder. This is an example of Inversion of Control principle.
Spring also provides these ConfigurerAdapter hook points, where you can tweak the default configuration of an already instantiated component.
This is exactly what is happening in your Configuration class.

Why #Resource can't work in HttpServlet?

I am tiro to Spring, and want to use auto wire with annotation #Resource in my servlet.
In service layer and dao layer, this annotation works well, when I use it in my Servlet, the exception comes:
com.fruit.action.merchant.MerAdd.service name='merAddService' is an unknown #Resource
as you see, MerAdd is a servlet extends my own BaseServlet which extends HttpServlet, service is an object of MerAddServie, in MerAdd servlet:
#Resource(name="merAddService")
private MerAddBusiness service;
public MerAddBusiness getService() {
return service;
}
public void setService(MerAddBusiness service) {
this.service = service;
}
Is there anything I should do to fix this problem, mybe I misunderstand #Resource, can you help me , thanks ahead~
Unfortunately You cannot autowire using #Resource annotaion in Servlet.
Same Question is discussed in this spring forum link
Problem:-"The problem here is that some J2EE components have dependencies injected into them by the web container. Which means that #Resource() annotations won't work -- the container will try to resolve those dependencies to JNDI (or somewhere else)."
Possible Workaround:-
As you can use #Autowired annotation in your servlet
So You can delegate request processing to the dedicated bean which will have #Resource Bean autowired in it , i.e. make your servlet to be just an entry point that conforms to the API supported by servlet container. Hence, you can configure that actual business logic holder bean as necessary via spring and just retrieve it from IoC container and call necessary method from the servlet

Does this annotation work for Spring declarative transaction

As far as I know, Spring uses JDK to generate dynamic proxy for the classes that implement any inferface while use Cglib to generate dynamic proxy for the classes that do not implement any inferface. For decarative transcation, Spring uses proxy to add transaction aspect. Please take a look at the code below:
interface Demo {
void methodA();
}
public class DemoImpl implements Demo{
#Transactional
public void updateA() {}
#Transactional
public void updateB() {}
}
I think updateA can work well with transaction. But how about updateB method? Does the #Transactional work for it?
Maybe my understanding is not correct. It's great if the related Spring source code is provided to explain how Spring use JDK/cglib to proxy the class and interface. Thanks
I have the config in the xml:
<tx:annotation-driven transaction-manager="transactionManager" />
JDK dynamic proxy
In this case your bean is wrapped with a proxy implementing Demo interface. From that moment you can only use that interface. Trying to inject or fetch bean of DemoImpl type will result in dreadful Abstract DAO pattern and Spring's "Proxy cannot be cast to ..." problem!
This kind of answers your question - you can only access updateA() and this is the only transactional method. Annotation around updateB() is ignored.
However if you call updateB() from updateA() it will be transactional because it will bind to a transaction started by updateA() (with default transaction propagation).
CGLIB proxy
In this case the interface is ignored. cglib will create a subclass of DemoImpl (obviously also implementing Demo interface) and apply transaction behaviour on both update*() methods. Now if you inject bean of type DemoImpl (interface is not needed in this case at all and Impl suffix is ugly) you can safely and transactionally call both methods.
See my article: Spring pitfalls: proxying and Spring AOP riddle for greater details.

aspectj and spring with aspectj-autoproxy

I've declared my aspects using the #Aspect annotation, but the advice does not seem to get applied. The aspect works in a few other projects that I have, and the key difference seems to be that the other projects are completely wired using annotations, and this particular project is xml wired. The only bean that is annotation wired is the Aspect. So I'm wondering if spring's aspectj support, when using aspectj-autoproxy is sensitive to order that the beans are defined in the xml.
For example, will beans declared after aspectj-autoproxy in xml be considered for AOP pointcuts?
EDIT:
I moved the <aop:aspectj-autoproxy /> until after all beans are created and still no luck.
Basically my code consists of:
#Component
#Aspect
public class SomeAspect {
#Pointcut("#annotation(MyAnnotation)")
public void isX() {}
#After("isX()")
public void XX() {
System.out.println("Called aspect");
}
}
And my controller has something like:
public class XController extends AbstractCommandController {
#MyAnnotation
public void handleX(...) {
// do stuff
}
#Override
protected void handle(...) {
return handleX(...);
}
}
And then the spring xml is:
<context:component-scan base-package="package.of.some.aspect" />
<aop:aspectj-autoproxy />
<!-- the rest of the beans below -->
<bean id="someController" class="..." />
My previous projects captured and loaded all beans via the component-scan. That's what's different this time.
EDIT2:
The other difference is that the other projects are using #Controller, and #RequestMethod. And in this case I'm using a derived class of AbstractCommmandController. I'm wondering if this applies:
http://forum.springsource.org/archive/index.php/t-46637.html
Namely that I can't apply advice to any method except handleRequest().
EDIT3:
My latest try is to override handleRequest() and apply my annotation there. Under the assumption that when spring proxies my controller it will see the annotation and apply the advice, since it's calling through the public, externally called method. This still doesn't work.
I see that you are calling the method handleX directly from another method in the same class. This will not respect the annotiation, as the work of processing AOP annotations is done by a JDK proxy that wraps your class and exposes the same interfaces.
It's possible that you can work around this by using CGLIB instead of JDK proxies, but in my experience, the most reliable solution is just not to rely on any AOP annotations for methods called internally.

How does Spring annotation #Autowired work?

I came across an example of #Autowired:
public class EmpManager {
#Autowired
private EmpDao empDao;
}
I was curious about how the empDao get sets since there are no setter methods and it is private.
Java allows access controls on a field or method to be turned off (yes, there's a security check to pass first) via the AccessibleObject.setAccessible() method which is part of the reflection framework (both Field and Method inherit from AccessibleObject). Once the field can be discovered and written to, it's pretty trivial to do the rest of it; merely a Simple Matter Of Programming.
Java allows you to interact with private members of a class via reflection.
Check out ReflectionTestUtils, which is very handy for writing unit tests.
No need for any setter, you just have to declare the EmpDao class with the annotation #component in order that Spring identifies it as part of the components which are contained in the ApplicationContext ...
You have 2 solutions:
To manually declare your beans in the XML file applicationContext :
<bean class="package.EmpDao" />
To use automatic detection by seeting these lines in your context file:
<context:component-scan base-package="package" />
<context:annotation-config />
AND to use the spring annotation to declare the classes that your spring container will manage as components:
#Component
class EmpDao {...}
AND to annotate its reference by #Autowired:
#Component (or #Controller, or #Service...)
class myClass {
// tells the application context to inject an instance of EmpDao here
#Autowired
EmpDao empDao;
public void useMyDao()
{
empDao.method();
}
...
}
Autowiring happens by placing an instance of one bean into the desired field in an instance of another bean. Both classes should be beans, i.e. they should be defined to live in the application context.
Spring knows the existence of the beans EmpDao and MyClass and will instantiate automatically an instance of EmpDao in MyClass.
Spring uses the CGLib API to provide autowired dependency injection.
References
Usage of CGLib forum comment by Rod Johnson
3.3.1. Injecting dependencies
Pro Spring - Analyzing Spring Dependencies
Further Reading
Introduction to the Spring Framework by Rod Johnson

Resources