动态代理
AOP中的代理就是由AOP实现框架动态生成的一个对象,该对象可以作为目标对象使用。
spring中的AOP代理,可以是JDK动态代理,也可以是CGlib代理
JDK动态代理实现
JDK动态代理是通过java.lang.reflect.Proxy类来实现的,我们可以调用Proxy类的newProxyInstance()方法来创建代理对象
注意:JDK动态代理,被代理的目标类必须实现接口,才能产生代理对象
- 创建接口UserService
public interface UserService {
public void save(String name);
public String getById(int id);
}
- 创建实现类UserServiceImpl
public class UserServiceImpl implements UserService{
@Override
public void save(String name) {
System.out.println("添加用户:" + name);
}
@Override
public String getById(int id) {
System.out.println("查询用户,用户id为:" + id);
return "xiaoming";
}
}
- 创建代理类JDKProxy
public class JDKProxy {
//获取代理
public Object getProxy(Object tarObj){
/*
* 参数一:目标类的类加载器
参数二:目标类实现的接口
参数三:回调,代理对象调用方式时执行invoke
*/
return Proxy.newProxyInstance(tarObj.getClass().getClassLoader(),
tarObj.getClass().getInterfaces(), new InvocationHandler() {
//代理对象调用方式时执行invoke
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object o = method.invoke(tarObj,args);
System.out.println("JDK其他业务");
return o;
}
});
}
}
- 测试
public class ProxyTest {
public static void main(String[] args) {
JDKProxy jp=new JDKProxy();
UserService us= new UserServiceImpl();//目标类对象
UserService usproxy= (UserService) jp.getProxy(us);
usproxy.save("里么名");
usproxy.getById(1);
}
}
- 结果
CDLIB代理实现
JDK动态代理有一定的局限性,就是使用动态代理的对象必须实现一个或多个接口;而CGLIB代理,接口可实现可不实现
-
上面的接口UserService
-
上面的实现类UserServiceImpl
-
创建代理类CGlibProxy
public class CGlibProxy {
public Object getProxy(Object tarObj){
//创建一个动态对象
Enhancer en=new Enhancer();
en.setClassLoader(tarObj.getClass().getClassLoader());
en.setInterfaces(tarObj.getClass().getInterfaces()); //没有实现接口时不需要
//确定需要增强的类
en.setSuperclass(tarObj.getClass());
//添加回调函数
en.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
Object ob = method.invoke(tarObj,objects);
System.out.println("CGlib其他业务");
return ob;
}
});
//返回创建的代理类
return en.create();
}
}
- 测试
public class ProxyTest {
public static void main(String[] args) {
CGlibProxy cp = new CGlibProxy();
UserServiceImpl us= new UserServiceImpl();//目标类对象
UserService usproxy= (UserService) cp.getProxy(us);
UserServiceImpl usproxy= (UserServiceImpl) cp.getProxy(us);//没有实现接口
usproxy.save("水电费");
usproxy.getById(1);
}
}
- 结果