spring框架详解(四)--AOP代理

来源:互联网 发布:中科软件怎么样 编辑:程序博客网 时间:2024/06/06 02:45

一.aop代理的概念与作用

    生活中做过微商或者产品销售的,都有个代理的概念.最上级是总代理,下面二级代理,三级代理之类的.他们的目标就是把客户想买的东西跟他们买.用户不需要去生产厂家去.说简单点,那些专卖店都是产品代理,你要买东西直接去他们那里买就可以了,而不用去厂家买.
    aop代理:要为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能,例如,异常处理、日志、计算方法的运行时间、事务管理、等等,你准备如何做?  -编写一个与目标类具有相同接口的代理类,代理类的每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码
    你把它想成生活中不是差不多吗?相同接口,好比,你是耐克专卖代理店你不可能去卖阿迪达斯的鞋子.增加的系统功能好比你可以在不违反市场价格的情况下,自己定时做个活动打个折之类的.所以java这种就是面向对象生活的语言,结合生活你会发现好理解很多.
  

如果采用工厂模式和配置文件的方式进行管理,则不需要修改客户端程序,在配置文件中配置是使用目标类、还是代理类,这样以后很容易切换,譬如,想要日志功能时就配置代理类,否则配置目标类,这样,增加系统功能很容易,以后运行一段时间后,又想去掉系统功能也很容易。

aop代理分类:
    静态代理的每一个代理类只能为一个接口服务,这样一来程序开发中必然会产生过多的代理,而且,所有的代理操作除了调用的方法不一样之外,其他的操作都一样,则此时肯定是重复代码。解决这一问题最好的做法是可以通过一个代理类完成全部的代理功能,那么此时就必须使用动态代理完成。    
   动态代理  与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。

实例:
    新建一个接口
public interface UserDao {public void addUser();//添加用户public void deleteUser();//删除用户}
  它的实现类
public class UserImp implements UserDao{public void addUser() {System.out.println("正在添加用户....");}public void deleteUser() {System.out.println("正在删除用户....");}}
用户代理类
public class UserProy implements InvocationHandler{private UserDao userDao;public UserProy(UserDao uDao) {super();this.userDao=uDao;}public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println("开启事务");method.invoke(userDao);System.out.println("提交事务");return null;}}
时间代理类
public class TimeProy implements InvocationHandler {private UserDao userDao;public TimeProy(UserDao uDao) {this.userDao=uDao;}public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println("start time:" + new Date());method.invoke(userDao);System.out.println("end time:" + new Date());return null;}}

测试
public class Test {public static void main(String[] args) {   UserDao uDao=new UserImp();   InvocationHandler handler = new UserProy(uDao);   InvocationHandler handler1 = new TimeProy(uDao);   UserDao userProy=(UserDao) Proxy.newProxyInstance(uDao.getClass().getClassLoader(), uDao.getClass().getInterfaces(), handler);   UserDao userProy2=(UserDao) Proxy.newProxyInstance(userProy.getClass().getClassLoader(), userProy.getClass().getInterfaces(), handler1);   userProy2.addUser();   System.out.println("======================");   userProy2.deleteUser();}}

Proxy.newProxyInstance的三个参数分别表示什么含义?
ClassLoader loader   ----指定被代理对象的类加载器
Class[] Interfaces   ----指定被代理对象所实现的接口
InvocationHandler h  ----指定需要调用的InvocationHandler对象