AOP without Spring - java

I implemented Logger using Spring 4.0 and AspectJ. But I'm now trying to make the logger independent of Spring. I couldn't initialize aspect in my application. Any hint to start will be helpful.
Thanks in advance.

If you have a Spring- based app and you want to use AspectJ, it is better to use the AspectJ features offered by Spring. You can also use Spring AOP without AspectJ.
You can make cross-cutting functionality by using AspectJ annotations with Spring AOP.
#Aspect annotation allow you to make the aspect from your Logger class.
In the Logger class define set of the pointcut by using the #Pointcut annotation. By using annotations #Before, #AfterReturning, #AfterThrowing define the advices and when they will be applied relative to the set of the pointcut (before, after, in the case of throwing an exception).
Then include the aop namespace in Spring configuration file and register the object of the class AnnotationAwareAspectJAutoProxyCreator by using <aop:aspectj-autoproxy> configuration element.
This component also performs proxying of classes which have #Aspect annotation and which have methods included in a certain set of the pointcut.
How to use AspectJ without Spring you can find here, for example:
Using AspectJ logging without Spring

Related

Usage of #Valid vs #Validated in Spring

Thanks to this question, I think I understand how validation is working.
As for JPA, here we have a specification called JSR-303 explaining how Bean Validation should work and then we are using implementations like the commonly used Hibernate Validator or Apache BVal also.
I am struggling about using #Validin some part of my code. I am not using #Validated because I do not need group validation.
You can find an example of a demo project here
In PropertyExample class, you can see I marked my class for bean validation to happen.
When using #Validated, everything work as expected since I am violating a constraint in my application.yml file.
When using #Valid over #Validated, it seems nothing happens. I do not understand why.
I saw too that those annotations could be used on ElementType.PARAMETER but when I am using using them during constructor initialisation, validation doesn't seem to trigger either.
Explanations on how to used those annotations (especially the #Valid) would be greatly appreciated.
It works when using Validated and doesn't when using Valid simply because Spring Boot requires properties classes to be annotated with Validated if you want them to be validated. See the documentation:
Spring Boot attempts to validate #ConfigurationProperties classes whenever they are annotated with Spring’s #Validated annotation
[...]
You can also trigger validation by annotating the #Bean method that creates the configuration properties with #Validated.
Note that they can't possibly allow the use of Valid on properties classes, since the Valid annotation isn't applicable to classes.

Replacement class for MultiActionController which is deprecated in 4.3.3

While fixing all the deprecated api's when upgrading to Spring 4.3.3, I'm facing an issue with the MultiActionController class which is used in multiple locations.
Are there any alternative classes in spring which have the same functionality as MultiActionController?
As per the spring docs:
as of 4.3, in favor of annotation-driven handler methods ,we need to
follow annotation .
Are annotations the only solution or are there any other classes or workarounds?
As far as I'm aware, annotations are the only way now, unless you're willing to use the deprecated MultiActionController class.
In the javadoc for the MultiActionController class, they state that it's deprecated in favor of annotations, so logically there should be an annotation to replace (or at least mimic) the majority on methods within the class. They don't list any other alternatives or workarounds so I doubt there are any. The methods don't specify anything either.
Here is the Spring 4.3.3 framework reference which could aid you in tracking down the annotations you're looking for. Section 30.6 - Annotation-driven listener endpoints would be a good place to start.
Here is a page on Migrating to spring framework 4.x, and finally, a page on Converting a Spring Controller into a #Controller. These links should point you in the right direction.

Spring aop intercepting calls from within the same service class

I have a same scenario as mentioned in
Spring #Transaction method call by the method within the same class, does not work?
I was referring to answer #1 which i thought would work for my simple pojo class but it didnt. In my case i dont have annotation #Transaction. Its a simple pojo class. I wish to intercept each method adduser as well as addusers using spring aop if i take example in post above.
Is it possible to intercept method that is being called from the same service call? I was referring to AspectJAwareProxy which does the trick but doesnt resolve the issue as a whole. What i mean is i dont want anything to be added to my business logic. So i want to avoid any coding except for defining pointcut and defining the advice. Is it something possible using Java and spring aop? I am using CGlib to generate proxy. Spring version is 3.0.5.Release.
Thanks,
Ajay
For this to work, you have to use load-time weaving instead of proxying. The reason is because spring uses proxying to achieve AOP functionality (such as transaction support). Once inside a class instance, any method-calls to methods in the same instance will be directly against the actual instance object, not the wrapping proxy so AOP advices will not be considered. Load-time weaving works differently. There, you have an outside java agent that manipulates the classes on a byte-code level to inject the AOP support.
You will need to
1: Modify your java command-line used to include the spring aspectj agent
2: add
<context:load-time-weaver aspectj-weaving="on" />
<tx:annotation-driven mode="aspectj" />
to your spring cofig.
Read more:
AspectJ Load Time Weaving with Spring Transaction Manager and Maven
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-aj-ltw

Spring annotations conflicts with my design guidelines

Overview
Using
Spring 3.0.1 (annotation configuration)
Current configuration is using CGLib as proxy creator but this is not my preference
Transactions are annotation configured without any special settings
All configuration is done with annotations (#Service, #Transactional, #ManagedResource, #Inject, etc.)
Hibernate 3.5 (entities are annotated with javax.persistence)
Guidelines highlights
Every bean annotated with #Repository or #Service must have an interface
Constructor DI (when re-configuration isn't required)
Constructor has default visibility (Foo(Bar bar) {...})
Bean fields are final (when re-configuration isn't required)
Leads to no default constructor
Implementations are default visible with final modifier (final class Foo)
The Problem
CGLib can't proxy final classes
CGLib requires default (empty) constructor
Some services are required to be exposed via JMX
MBean exporter can't work unless proxied by CGLib
Some #Transactional #Services are accessed via facade service which requires more than one service to include in the facade transaction (e.g. Observer service over 2 application components)
Some interfaces have more than one implementation (which currently distinguished by #Qualifier)
Future guideline (or nice to have feature) - each application module will have beanRefContext.xml file to configure its internal application context
When I used to work with XML configuration I was able to enforce all the guidelines I presented above, but when switching to annotations it seems like Spring is misbehaving.
Developers in my group prefer annotation configuration (I seems easier to wire and write new code), but I've noticed all kind of "hacks" they introduce to the code to prevent from dealing with Spring application context failures.
The Question(s)
Are there best practices I should follow when using annotation configuration?
When using more than one implementation per interface (trying to reduce the use of #Primary or #Qualifier)
When using #Transactional
When using #ManagedResource
When using a combination of the above
Is there a way of stop working with CGLib, keep the annotation configuration and still be able to export my MBeans with annotations?
What is the suitable implementation for keeping most (preferably, all) of my guidelines?
I came up with the following solution (to questions #2 and #3) to be able to enforce my design guidelines and keep using annotation based configuration:
Each dependent project (Maven module) has it's own ApplicationContext
Every dependent project application context is defined in beanRefContext.xml
These application contexts are loaded in hierarchy using Spring context hierarchy mechanism.
This step is actually not fully supported by Spring and requires additional work
Since my application is layered, I could disable CGLib on all my modules besides the JMX layer (I can live with it :-) ).
The above steps also enabled me to reduce the execution time of Spring aware tests (every module loaded only a sub-set of beans).
As a practical guideline (for question #1), if an interface has more than one implementation, I place #Primary on the widely used one and other clients, requiring another implementation, wire the bean using #Qualifier.
Answer to point 2)
You could use AspectJ instead of CGLib.

If a Controller has a #Controller annotation, shouldn't that be enough for Spring without component scanning?

According to the Spring docs, to enable autodetection of annotated controllers, you add component scanning to your configuration:
<context:component-scan base-package="org.springframework.samples.petclinic.web"/>
My question is, why is this necessary?
If a Controller has an annotation to already indicate what it is, shouldn't that be enough for Spring without component scanning?
How else would Spring find the classes? If you haven't told Spring to look in a certain class or package, those classes aren't going to get loaded, and Spring is never going to find them.
This is more a limitation of the java classloading model (if you can call it a limitation), then it is a limitation of Spring.
You only have to put the following in your configuration:
<context:annotation-config/>
If you only put the annotation on your class, the framework had to load all the classes to check if the annotation is present.
To minimize this overhead, you have to put the annotation-config tag in your configuration. That way the framework knows it has to check the classes from that configuration.
You can help the framework by specifying the package where your annotated classes are with the "base-package" attribute.
//EDIT//
This also explains the note in the documentation:
Note
<context:annotation-config/> only
looks for annotations on beans in the
same application context in which it
is defined. This means that, if you
put in a
WebApplicationContext for a
DispatcherServlet, it only checks for
#Autowired beans in your controllers,
and not your services.
Simply annotating a class with #Controller doesn't necessarily mean you want it to be part of your Spring context. Imagine if the class is part of another application, or part of a third party library, or a deprecated component of your system, etc. Just because it is on the classpath doesn't necessarily mean that you want it automatically instantiated as a bean in your Spring context.

Categories

Resources