What is interface-based proxying? - java

I was reading this regarding to where to place Transactional(interface vs implementation):
The Spring team's recommendation is that you only annotate concrete classes with the #Transactional annotation, as opposed to annotating interfaces. You certainly can place the #Transactional annotation on an interface (or an interface method), but this will only work as you would expect it to if you are using interface-based proxies. The fact that annotations are not inherited means that if you are using class-based proxies then the transaction settings will not be recognised by the class-based proxying infrastructure and the object will not be wrapped in a transactional proxy (which would be decidedly bad). So please do take the Spring team's advice and only annotate concrete classes (and the methods of concrete classes) with the #Transactional annotation.
So the question is what is interface-based proxy exactly and how can I see if it is used? Is it some configuration or it is the way how I instantiate/use instances?

If Spring cannot create a JDK proxy (or if you force Spring to create a CGLIB proxy by setting proxyTargetClass to true) then the code will not execute in a transactional context because (as the Spring docs state):
The fact that annotations are not inherited means that if you are using class-based proxies then the transaction settings will not be recognised by the class-based proxying infrastructure and the object will not be wrapped in a transactional proxy
So, I think your concerns are:
How can you be sure that Spring does not create a CGLIB proxy
You must be configuring AOP based transactional support. If you are doing this by using <tx:annotation-driven/> then the default value for proxy-target-class (false) will suffice though could be explicit about this by setting: <tx:annotation-driven proxy-target-class=“false"></tx:annotation-driven>. If you are configuring transactional support in some other way (using Java config, for example) then just ensure that the value of TransactionProxyFactoryBean.proxyTargetClass is false.
How can you be sure that your #Transactional annotations are respected
This is easy, just annotate the concrete class with the #Transactional annotation instead of annotating the interfaces. This avoids any issues with proxying.
In summary, Spring should use interface based proxying as long as TransactionProxyFactoryBean.proxyTargetClass is false however, if you annotate a concrete class rather than an implementation then the issue of proxying won't affect transactional support.

Related

How to force Spring proxy generation for annotated #Transactional methods

I use multiple TransactionManagers with #Transactional("txXyz") annotations. It works well in beans annotated with #Component and created during Spring startup. I have another type of beans that I create later in runtime via
applicationContext.getAutowireCapableBeanFactory().createBean(beanClassName)
The latter approach successfully injects #Autowired resources and calls all interface hooks (e.g. InitializingBean). However it doesn't create transactional proxies for annotated methods. I have been looking around but haven't found an obvious way to force transactional proxi generation on createBean. My question is there a "legal" way to force transactional proxy processing for beans created when application is already running?

jpa:repositories / #EnableJpaRepositories vs #Repository - spring

Does using the #EnableJpaRepositories or jpa:repositories (on the xml) gives the developer not to use #Repository tag of Spring? As I look on the example guidelines of Spring most of their examples is that they do not use the #Repository tag anymore on their interfaces that extends JpaRepository or CrudRepository interface of Spring Data.
I tried to use them together but Intellij warns me that it can not autowired my repository because there is more than one bean. I tried to remove the jpa:repositories on my xml file but the an error appeared that the application can not create a bean for my entity manager.
These are two different things. #Repository annotation is much older than Spring Data and is used to tell Spring to translate all exceptions thrown by #Repository annotated components to DataAccessException (more to read here: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/stereotype/Repository.html)
In SpringData you have #EnableJpaRepositories + entire underlying scanning and repository bean generation mechanism and there is no need to mark your repository interfaces (or custom classes) with #Repository.
The Spring Data Documentation is IMHO not entirely clear about this.
In chapter 3.1.1 it says:
Using the repositories element looks up Spring Data repositories as described in “Creating Repository Instances”. Beyond that, it activates persistence exception translation for all beans annotated with #Repository, to let exceptions being thrown by the JPA persistence providers be converted into Spring’s DataAccessException hierarchy.
To me this sounds like you would still need to add #Repository explicitly in order to activate persistance exception translation.

How can I create a proxy for a service in HK2

I am using Jersey 2.x and HK2 which is built-in into Jersey.
I need to decorate certain methods in my services marked by annotation, i.e. I'd like to perform some additional actions before and after such methods calls. Unfortunately, HK2 doesn't have any AOP capabilities. I thought that I could bind my factory to a service's interface and create a proxy of the service whenever factory's provide method is called. However, I need a couple of things to my factory to work:
1) the service's class and interface to create a proxy
2) ServiceLocator instance to properly inject all service's dependencies
And I just don't see any way to have both. If I bind factory using bindFactory(MyFactory.class) then I can't pass information about the service into it, but can have ServiceLocator instance injected into it. And if I bind factory using bindFactory(new MyFactory(Service.class, ServiceImpl.class)) then I have information about the service, but I don't have ServiceLocator instance to properly create that service, because HK2 doesn't inject anything into factories instances and I don't see anyway to get a ServiceLocator instance from AbstractBinder to provide my factory with locator during binding.
I would really appreciate any suggestions and recommendations. I hope I am not the first one who wants to uniformly proxy my services.
In the most recent version of hk2 (2.2.0-b25) we have added the ability to add AOP alliance interceptors to any method. But this feature is not yet fully baked (we will be adding constructor injection) and not yet fully documented. But you might want to start playing around with it, as it will give you the ability to add AOP MethodInterceptors to any method on your service.

Springs #Transactional only works for proxy

I have a method that uses Springs #Transactional for database rollbacks. It works fine when i define the transaction manager like this:
<tx:annotation-driven transaction-manager="txManager" mode="proxy" />
but when i change to mode="aspectj" it does not rollback when the method throws an exception.
are there some differences in how the two modes should be used?
The "aspectj" mode will only work if load-time weaving or compile-time weaving are enabled. If not then the #Transactional annotation will not be applied to the annotated method.
The default proxy mode cannot be used to annotate private methods. This is where aspectj mode is useful. Certain frameworks (such as W2O for Web Services) require the class type itself to work. This can be impossible using proxy mode as the class is wrapped in a proxy class wrapper. This is another reason for using AspectJ.
If public methods are used and there are no special framework restrictions, then proxy mode is sufficient.
See Also: Transaction Management

Spring MVC #Controller and profiles

I have a spring mvc controller and I want to enable it only in some profiles (for example development and test).
I know I can use the profile attribute of the beans element in xml configuration to limit the scope of my beans, but I'm using convenient annotations for the controllers now.
Can I bind the annotated controller to given profile somehow?
Or do I have to use the "old way" (of implementing and declaring controller) without annotations and use the beans element in xml configuration?
Will the annotated controllers mix well with the "old ones"?
EDIT: another way, which comes to my mind, is to check the profile in runtime from autowired Environment instance, but this denies the inversion of control
Is this what you mean ?
#Controller
#Profile("test")
public class CacheController {
}
javadoc

Categories

Resources