I am new to Spring AOP, I want some help to
i have MultiActionController ,this is annotaion based.
i defined pointcut for method and advisor in spring configuration file.
i am calling that method from my controller.
Now my question is: How to define pointcut annotation in controller?
Please give me some hints.
Thanks in Advance.
The whole point of AOP is that you don't define the pointcuts in the target classes, but in external aspect classes (or in case of XML-based Spring AOP, in XML).
So if you have both your controller and the aspects in the same ApplicationContext (and the pointcuts match the controller methods), the advices should be applied automatically.
However, there is a caveat:
Spring AOP will only work the standard (JDK-proxy based) way if you use interfaces to back your controller.
If you do use interfaces consider this note (source):
Note
When using controller interfaces (e.g. for AOP proxying), make sure to consistently put all your mapping annotations - such as #RequestMapping and #SessionAttributes - on the controller interface rather than on the implementation class.
And if you don't, you must set proxy-target-class="true" as described in the section Proxying mechanisms.
Related
We can create proxy for the target bean in the postProcessAfterInitialization() method of BeanPostProcessor.
Or we can use AOP - and proxy will also be created through Dynamic Proxy or CGlib.
What is the difference?
When should we use BPP and when AOP?
As far as I know bean-post-processor is a more powerful tool. It can complete replace the bean (so you can even shoot in your own foot). On the other hand AOP approach has very handy pattern matching solution. In a bean-post-processor approach you get an Object and you have to recognize what is its type. Moreover AOP approach is more about adding a behaviour related to pattern-selected methods' execution. With bean-post-processor you can replace (or just modify) a whole bean which possibly affects all of its method.
From a software design perspective, when should we use #Component instead of a traditional Java class (that needs to be explicitly instantiated by 'new')? For example, if we need to create a class that is one of the following patterns:
Adapter
Bridge
Façade
Strategy
Translator
Should the class have the #Component annotation (or any Spring derivative annotation such as #Repository/#Controller/#Service)?
Spring applies the Inversion of Control principle, which drills down to that the framework handles stuff for you, so you don't have to worry about it.
By using #Component on the class you let Spring create a bean for you.
This way Spring can, for example, inject this bean on runtime when you need it. (For example by Autowiring your constructor).
It is up to you to decide if you want to make use of this functionality for your class. A facade for example could very well be a Spring component, this way you could possibly inject an API implementation that is exposed via a facade on runtime, without the need to think about the dependency injection implementation.
I would not recommend using this annotation on a DTO or model class for example. These classes mostly consist of data and don't fit the need to be managed by Spring.
Other interesting related questions that can help you decide when to create a component:
What's the difference between #Component, #Repository & #Service annotations in Spring?
Spring: #Component versus #Bean
I have a Spring project uses annotations to apply (among other things) caching.
My understanding is that these annotations will only work when #Autowired and called through SpringAOP.
This means that if a method calls another in the same class, then any annotations on the second method are ignored e.g.
#Cacheable(...)
public Animal getAnimal(int id) {
return get(m_url, id);
}
public Cage getCagedAnimal(int id) {
Animal animal = getAnimal(id); // This call will not apply #Cacheable
Cage cagedAnimal = new Cage(animal);
return cagedAnimal;
}
What I am looking for is a way to enforce against this i.e. public methods should not be able to call other public methods of the same class.
I tried applying something similar to the approach used here http://www.jayway.com/2010/03/28/architectural-enforcement-with-aid-of-aspectj but it falls short when applying the restriction on the same class.
It's perfectly doable, AspectJ is very powerful. But you seem to be using Spring AOP instead of AspectJ, and Spring AOP is quite limited compared to AspectJ. Spring AOP works by creating proxies around your actual bean implementation to implement the AOP features it provides. When the proxy gets the call, the advices will be applied and flow control will be passed to the normal bean. Should the normal bean (the target of the proxy) invoke another methods on itself, it won't be invoked on the proxy so the AOP part will be bypassed. AspectJ doesn't have that limitation as it's modifying your classes, not just creating proxies around them. I would strongly suggest to go with AspectJ instead of Spring AOP. Spring will work great with AspectJ too.
How would you extract something prior 2.5 version from .xml config? It bothers me because if #Autowired is removed from my arsenal I would not really know what to do.
Say I want to use some DAO implementation.
In service class I usually write:
#Autowired
someDaoInterface generalDao;
Then I typically call
generalDao.someInterfaceMethod(someParam param);
How would I extract implementation from config in Spring 2.0 to use this method?
Is it as dumb as just: new ApplicationContext(pathToXml) and then use .getBean or there is other way?
Why do I ask for taking bean out from configuration file?
Because in Spring MVC how can you perform your logic without getting beans out from the application context.
If you have #Controller handler then you need to make calls to the service classes' methods? So they should be somehow retrieved from the context and the only way so far is using #Autowired? Then I would also want to populate Service classes as I stated in previous example with DAO classes and they also need to be retrieved from the application context, so I would be able to write logic for service classes themself. How would people do it in the past?
I see the #Autowired as the only mean of taking something out, not because it is convenient to wire automatically - I am perfectly ok with XML.
You still have option to wire it explicitely via property or constructor parameter. (Anyway, autowired is not going to work if there is ambiguity in your container )
Of course, you can use application context and getBean() in your java code, but it violates DI pattern and makes all the spring stuff useless. Purpose of DI is to decouple your business loginc from implementation details - it's not business logic it's how and where it dependencies come from. Dependencies are just there.
By using ApplicationContext.getBean() you are breaking this pattern, and introduce dependency to:
spring itself
your configuration names
After you done this, you can as well drop use of DI and spring because you just voided all the advandages DI is providing to you. (BTW, #Autowired also introduces dependency to spring, and violates DI pattern, it also implies that there is only one instance available)
Also, answer is: in ideal case there shall be no reference to spring in your code at all.
No imports, no annotations - just interfaces of collaborating entities.
Can an annotated Spring MVC Controller also be annotated with #Component/#Service type of annotations and be used both as a controller and as a bean?
Edit: placing more emphasis on the software design aspect, and updating the API link to SpringV3
As mentioned in other answers, this is not an ideal approach to Spring MVC, but nevertheless the controller will already be available for autowiring in your ApplicationContext.
It's already a Bean in your ApplicationContext, so you can auto-wire it by type. There's no need to add an #Component annotation.
From the Spring API Docs: "This annotation serves as a specialization of #Component, allowing for implementation classes to be autodetected through classpath scanning."
http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/stereotype/Controller.html
The same holds true for #Service.
Although I've done it myself, I would not normally recommend this design approach.
If possible, refactor the required functionality into a separate bean, which can then be (auto-)wired into both the #Controller, and any other bean, as required.
If, as you have commented, you are 'cornered' into this decision (as I was, by previous design choices), then so be it.
HTH
It can but it shouldn't. A web controller should be an entry point, nothing else.
Any reusable logic it performs should be in a dedicated service layer, not in the controller itself
No, sounds like it's doing too much. One or the other, not both. I don't know if it's possible (I doubt it), but I'm sure it's not advisable.
I think that you should hear more about patterns like Front Controller, MVC, DAO and Multitier architecture and so on.