简单设计动态代理,基本模拟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);// 判断是否属于被代理对象类型
}

最新文章

  1. Android学习笔记(十)
  2. 遗传算法的简单应用-巡回旅行商(TSP)问题的求解
  3. How to set colors of HTML tables
  4. 【Protle99SE】PCB中各层的含义【小汇】
  5. js之Math对象
  6. Oracle添加含有脏数据的约束
  7. IIS7二级域名添加同一证书
  8. 初学python之路-day10
  9. C#3.0 Lamdba表达式与表达式树
  10. [Go] golang连接redis测试
  11. 【Python全栈-JavaScript】jQuery效果
  12. Linux命令:source
  13. UVA12113-Overlapping Squares(二进制枚举)
  14. [hgoi#2019/2/24]玄学考试
  15. python 截取 取出一部分的字符串
  16. python之数据库内置方法以及pymysql的使用
  17. ubuntu18.10安装redis遇到问题
  18. TM1629A驱动程序
  19. 【C】——C语言字符串比较函数
  20. HDU2017新生赛 友好整数

热门文章

  1. 如何虚拟机里安装Win8操作系统
  2. CentOS SVN Failed to load JavaHL Library
  3. linux svn 自启动
  4. import.html 页面导出execl
  5. 哪个先执行:@PostConstruct和@Bean的initMethod?
  6. 总结 vb与数据库的连接方法
  7. 【转】SQL SERVER 日期格式化
  8. C#:ORM--实体框架EF(entity framework)(1)
  9. [日常] mysql的索引使用情况测试
  10. Maven配置私服仓库