动态代理-cglib
cglib的实现原理:
在内存里构造一个目标对象的子类对象,
返回一个目标对象的子类对象的代理对象。
向项目中添加jar包:
- asm-4.2.jar
- cglib-3.1.jar
UserDaoImpl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package com.course.dao.impl;
public class UserDaoImpl {
public void addUser(String userName) { System.out.println("Save user, userName = " + userName); }
public void deleteUser(Integer userId) { System.out.println("delete user, userId = " + userId); }
public void queryUser(Integer userId) { System.out.println("query user, user[userId=" + userId + ", userName=Jerry]"); } }
|
ProxyFactory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| package com.course.proxy;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy;
public class ProxyFactory implements MethodInterceptor {
private Object targetObject; public ProxyFactory(Object targetObject) { this.targetObject = targetObject; }
@Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { openTransaction(); Object invoke = method.invoke(targetObject, args); commitTransaction(); return invoke; }
public Object getProxyInstance() { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(targetObject.getClass());
enhancer.setCallback(this); Object proxy = enhancer.create(); return proxy;
} public void openTransaction() { System.out.println("open transaction"); } public void commitTransaction() { System.out.println("commit transaction"); } }
|
测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| package com.course.test;
import com.course.dao.impl.UserDaoImpl; import com.course.proxy.ProxyFactory;
public class Test {
public static void main(String[] args) { UserDaoImpl userDaoImpl = new UserDaoImpl(); ProxyFactory userDaoImplProxyFactory = new ProxyFactory(userDaoImpl); UserDaoImpl UserDaoImplProxy = (UserDaoImpl) userDaoImplProxyFactory.getProxyInstance(); String userName = "Tom"; UserDaoImplProxy.addUser(userName);
Integer userId = 1; UserDaoImplProxy.deleteUser(userId);
userId = 2; UserDaoImplProxy.queryUser(userId);
} }
|
总结
在Spring的AOP编程中,
如果加入容器的目标对象实现了接口,使用JDK动态代理
如果加入容器的目标对象没有实现接口,使用cglib动态代理
内部类
$
是内部类的标志
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package com.course.test;
import com.course.dao.impl.UserDaoImpl; import com.course.proxy.ProxyFactory;
public class Test {
public static void main(String[] args) { UserDaoImpl userDaoImpl = new UserDaoImpl(); ProxyFactory userDaoImplProxyFactory = new ProxyFactory(userDaoImpl); UserDaoImpl UserDaoImplProxy = (UserDaoImpl) userDaoImplProxyFactory.getProxyInstance(); System.out.println(UserDaoImplProxy.getClass().getSimpleName()); } }
|
一个.java
文件可以编译生成多个.clas
s文件,数量取决于.java
文件中定义的class类
的数量
一个.java
文件只能有一个public class
如果不是内部类,编译生成类名.class
,如果是内部类,生成外部类$内部类.class