jdk,cglib agent

jpa annotation requires cglib proxy? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

The proxy-target-class in annotation-driven is the injection method (for a bean, it is the interface injection corresponding to the jdk form, or the subclass injection of cglib)

Aspectj-autoproxy The way to generate aspect beans, (use jdk or cglib for proxy objects produced)

It can be used for producing proxy objects. Unless the target object has an interface, it can only use cglib injection. (cglib is used to inherit classes or implement interfaces to generate objects.) To use cglib, you need to add a jar package

Using jdk to proxy the target object must have an interface

Object cannot be final with cglib

 

 

Acting for Transactions:

Because we use the transaction based on service, the service is generated by the proxy, so the proxy mode and the working proxy mode of the transaction configuration should be consistent, otherwise the transaction will be invalid, or follow the label and write it on the implementation class method

 

http://sishuok.com/forum/blogPost/list/3845.html

 

<tx:annotation-driven transaction-manager="transactionManager" 

                                       proxy-target-class="true"/> injection method (cglib)

<!-- Enable @AspectJ-style aspect declaration--> <aop:aspectj-autoproxy proxy-target-class="true"/>, spring aspect generation proxy method

 

 

 

Behind Spring's @Transactional, SpringAOP is used to proxy our UserDao. There are two ways to proxy, jdk proxy or cglib proxy.

For example, the instance of UserDao is the object we want to proxy, which is called target for the time being

jdk代理针对那些实现了相应的接口的类,创建出的代理对象也是实现了同样的接口,同时该代理对象包含一个target

cglib代理针对类都可以进行代理,创建出的代理对象是继承了target类,同时该代理对象内部包含一个target(既可以是接口,也可以是直接的类(无接口的类))

注意:proxy-target-class属性值决定是基于接口的还是基于类的代理被创建。如果proxy-target-class 属性值被设置为true,

那么基于类的代理将起作用(这时需要cglib库)。如果proxy-target-class属值被设置为false或者这个属性被省略,那么标准的JDK 基于接口的代理将起作用。

 

@Transactional放到接口上 基于JDK动态代理也是可以工作的。

基于JDK动态代理 ,可以将@Transactional放置在接口和具体类上。(方法)

基于CGLIB类代理,只能将@Transactional放置在具体类上。(方法)

 

因此 在实际开发时全部将@Transactional放到具体类上,而不是接口上。(方法)

 

 

 

代理于spring data 

 

spring jpa搭建遇到的问题如果使用的代理不是cglib,会导致运行报错,

Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class org.jasig.cas.services.DefaultServicesManagerImpl]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class org.jasig.cas.services.DefaultServicesManagerImpl

at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:212)

at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:109)

at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:447)

 

<aop:aspectj-autoproxy/>

<tx:annotation-driven transaction-manager="transactionManager"/>

上面这一套不行,用的是jdk

下面这套可以:

 

 

 

代理于注入方式:

 

jdk代理:

把实现类注入给接口,否则注入不成功,比如在shrio权限动态加载中写的注意

cglib代理,被注入的类不需要接口,即可注入

 

 

代理于缓存

spring cache 是基于aop代理的缓存,当我们配置的缓存是jdk那么他可放在接口也可放在实现类,当定义的是cglib的话只能的定义在接口,

当我们的dao(mapper)的实现是代理产产生的那么应该是应jdk,此时可以配置在service(实现类,接口上)(mapper实现类,接口上)@Cacheable

但是如果<context:component-scan base-package="com.esteel.web" />扫描的是粗粒度的所有包(不仅仅是controller),那么 @Cacheable 放到service层无效

,有时@Transactional事务也会失效,这是都只能放到dao(mapper)接口层(因为其实现类直接由代理生成的,生成时即织入成jvm 运行时bean),如果是放在service层,由于扫描粒度大

导致内部一些问题所以失效

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326488566&siteId=291194637