一.cglib动态代理
1.CGLIB代理:
1,CGLIB可以生成目标类的子类,并重写父类非final修饰符的方法。
2,要求类不能是final的,要拦截的方法要是非final、非static、非private的。
3,动态代理的最小单位是类(所有类中的方法都会被处理);
2.在Spring中cglib和jdk代理选择:
若目标对象实现了若干接口,Spring就会使用JDK动态代理。
若目标对象没有实现任何接口,Spring就使用CGLIB库生成目标对象的子类。
对接口创建代理优于对类创建代理,因为会产生更加松耦合的系统,也更符合面向接口编程规。
cglib和javassist代理的机制都是一样的,都是通过继承实现的.
二.代码示例(Service接口及其实现类,请看上一篇jdk动态代理博文)
cglib动态代理类:
// 主要针对于类,采用继承于父类
@SuppressWarnings("all")
@Component("cglibProxy")
public class TransactionManagerCallBack implements org.springframework.cglib.proxy.InvocationHandler {
@Autowired
@Qualifier("target")
private Object target; //真实对象(被代理的对象):在此处指的是EmployeeServiceImpl
@Autowired
private TransactionManager txManager;
// 创建一个代理对象
public <T>T getProxyObject(){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass()); // 设置继承于哪一个父类
enhancer.setCallback(this); // this是InvocationHandler 增强的对象
return (T)enhancer.create(); // 创建一个代理对象
}
// 在真实对象上做增强操作
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object obj = null;
txManager.begin();
try {
obj = method.invoke(target, args); // 真实对象中的方法
txManager.commit();
} catch (Exception e) {
txManager.rollback();
e.printStackTrace();
}
return obj;
}
}
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- 解析autowired,resource,qualifier-->
<context:annotation-config />
<!--去哪些包下面去扫描组件-->
<context:component-scan base-package="com.shenzhenair.day02.common" />
<context:component-scan base-package="com.shenzhenair.day02.cglib_proxy" />
</beans>
测试类:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:com/shenzhenair/day02/cglib_proxy/cglibProxy.xml")
public class cglibProxyTest {
@Autowired
@Qualifier("cglibProxy")
private TransactionManagerCallBack callback;
//com.sun.proxy.$Proxy15
@Test
public void testSave(){
// 获得代理对象
// com.shenzhenair.day02.common.service.impl.EmployeeServiceImpl$$EnhancerByCGLIB$$820d8dfb
IEmployeeService service = callback.getProxyObject();
System.out.println(service.getClass());
service.save(new Employee());
}
}