JAVA两种代理模式

时间:2023-10-08 14:17:50

简单设计动态代理,基本模拟spring的动态代理方式。

before afterReturning around afterException after这些通知方法都可以这块模拟出来

spring的AOP:

1.在容器中的对象如果实现了接口则采用JDK的动态代理。

2在容器中的对象没有实现接口,则用(cglib)继承的方式实现动态代理。

现在模拟spring的动态代理。

首先准备接口(UserService)和实现接口的目标对象(UserServiceImpl)。

 public interface UserService {

 void save(); 

 }
 public class UserServiceImpl implements UserService {

     public void save() {
System.out.println("保存用户");
} }

1.动态代理

 /**
* 动态代理1
*
* @author shihaibin
* @param <T>
*
*/
public class UserServiceProxyFactory implements InvocationHandler { Object impl; public <T> Object getProxy(Class<T> clz) {
try {
impl = clz.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 生成动态代理
Object usProxy = Proxy.newProxyInstance(clz.getClassLoader(), clz.getInterfaces(), this);
// 返回
return usProxy;
} /**
* 参数:1.当前代理對象 2.当前方法 3.当前方法执行的时候的参数
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object invoke = method.invoke(impl, args);
after();
return invoke;
}
//可以重写
public void before() {
System.out.println("之后");
} public void after() {
System.out.println("之后");
}
}

测试:

 @Test
public void find1() {
// 简单的aop
UserServiceProxyFactory factory = new UserServiceProxyFactory();
UserService userServiceProxy = (UserService) factory.getProxy(UserServiceImpl.class);
userServiceProxy.save();
System.out.println(userServiceProxy instanceof UserServiceImpl);
}

2.cglib代理

 /**
* 动态代理2 cglib代理
*
* @author shihaibin
*
*/
public class UserServiceProxyFactory2 implements MethodInterceptor { public <T> Object getProxy(Class<T> clz) {
Enhancer en = new Enhancer();// 帮我们生成代理对象
en.setSuperclass(clz);// 设置对谁进行代理
en.setCallback(this);//回调函数
return en.create();// 创建代理对象;
} /**
* prxoyobj:被代理的原始对象 method:被代理的原始方法 arg:运行期的参数 methodProxy:产生的代理方法
*/
public Object intercept(Object prxoyobj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable {
// 打开事务
System.out.println("打开事务!");
// 调用原有方法
Object invokeSuper = methodProxy.invokeSuper(prxoyobj, arg);
// 提交事务
System.out.println("提交事务!");
return invokeSuper;
}
}

测试:

 @Test
public void find2() {
// 重写aop前后方法
UserServiceProxyFactory2 factoryContext = new UserServiceProxyFactory2();
UserService userServiceProxy = (UserService) factoryContext.getProxy(UserServiceImpl.class);
userServiceProxy.save();
// 判断代理对象是否属于被代理对象类型
// 代理对象继承了被代理对象=>true
System.out.println(userServiceProxy instanceof UserServiceImpl);// 判断是否属于被代理对象类型
}