Spring AOP 静态代理与动态代理

来源:互联网 发布:淘宝灯具都有3c认证吗 编辑:程序博客网 时间:2024/05/19 04:02

AOP:面向切面、面向方面、面向接口是一种横切技术

-横切技术运用:
- 事物管理:(1)数据库事物管理;(2)编程事物;(3)声明事物:Spring AOP–>声明事物
- 日志处理
- 安全验证:Spring AOP –OOP升级

静态代理原理:目标对象:调用业务逻辑 代理对象:日志管理

表示层调用–>代理对象(日志管理)–>调用目标对象

动态代理原理:Spring AOP采用动态代理来实现

1) 实现InvocationHandler接口
2) 创建代理类(通过java API): Proxy.newProxyInstance(动态加载代理类,代理类实现接口,使用handler);
3) 调用invoke方法(虚拟机自动调用方法)
日志处理
// 调用目标对象
method.invoke(“目标对象”,”参数”);
日志处理
通过代理对象–(请求信息)–>目标对象–(返回信息)–代理对象

Spring动态代理中的基本概念

// 通知类型try{    //前置通知         //环绕通知            //调用目标对象方法         //环绕通知    //后置通知  }catch(){    //异常通知  }finally{    //终止通知  }

流程图

静态代理原理实例

IUserServ接口代码

    public interface IUserServ {          List<User> findAllUser();          int deleteUserById(User user);          int saveUser(User user);      }  

UserServImpl实现类代码

    public class UserServImpl implements IUserServ {          public int deleteUserById(User user) {              System.out.println("******执行删除方法******");              return 0;          }          public List<User> findAllUser() {              System.out.println("*******执行查询方法*******");              return null;          }          public int saveUser(User user) {              System.out.println("*******执行添加方法********");              return 0;          }      }  

UserServProxyImpl实现类代码

/代理类:完成日志输出  public class UserServProxyImpl implements IUserServ {      // 访问目标对象(UserServImpl)      // 代理对象(UserServProxyImpl)      // 创建目标对象      private IUserServ iuserServ ;//= new UserServImpl();      public UserServProxyImpl(IUserServ iuserServ){          this.iuserServ = iuserServ;      }      public int deleteUserById(User user) {          beforeLog();          //调用目标对象里方法          iuserServ.deleteUserById(user);          afterLog();          return 0;      }      public List<User> findAllUser() {          beforeLog();          //调用目标对象里方法          iuserServ.findAllUser();          afterLog();          return null;      }      public int saveUser(User user) {          beforeLog();          //调用目标对象里方法          iuserServ.saveUser(user);          afterLog();          return 0;      }      private void beforeLog() {          System.out.println("开始执行");      }      private void afterLog() {          System.out.println("执行完毕");      }  }  

ActionTest测试类代码

    public class ActionTest {          public static void main(String[] args) {              //用户访问代理对象---信息->目标对象              IUserServ iuserServ = new UserServProxyImpl(new UserServImpl());              iuserServ.findAllUser();          }      }  

动态代理实例

IUserServ接口代码与UserServImpl实现类代码和上述代码相同

LogHandler类代码

    public class LogHandler implements InvocationHandler {          //目标对象          private Object targetObject;          /**          * 创建动态代理类          * @return object(代理类)          */          public Object createProxy(Object targetObject){              this.targetObject = targetObject;              return Proxy.newProxyInstance(                      targetObject.getClass().getClassLoader(),                           targetObject.getClass().getInterfaces(), this);          }          @Override          public Object invoke(Object proxy, Method method, Object[] args)                  throws Throwable {              Object obj = null;              try {                  beforeLog();                  //obj: 目标对象--->代理对象的返回值--->返回给调用者的信息                  //this.invoke("目标对象","代理对象给目标对象传递参数");                  //调用目标对象中方法                  obj = method.invoke(targetObject, args);                  afterLog();              } catch (Exception e) {                  e.printStackTrace();              }              return obj;          }          //日志管理方法          private void beforeLog(){              System.out.println("开始执行");          }          private void afterLog(){              System.out.println("执行完毕");          }      }  

ActionTest测试类代码:

    public class ActionTest {          public static void main(String[] args) {              //创建代理对象iuserServ              LogHandler handler = new LogHandler();              IUserServ iuserServ = (IUserServ)handler.createProxy(new UserServImpl());              iuserServ.deleteUserById(new User());          }      }  

运行结果:

开始执行
*执行删除方法*
执行完毕

Spring AOP代理

IUserServ接口代码与UserServImpl实现类代码和上述代码相同
LogAdvice中

    public class LogAdvice {          public void beforeLog(){              System.out.println("开始执行");          }          public void afterLog(){              System.out.println("执行完毕");          }      }  

applicationContext.xm中

    <!-- spring2.x后 -->          <!-- 目标对象 -->          <bean id="userServImpl" class="com.tarena.biz.impl.UserServImpl"/>          <!-- 通知 -->          <bean id="logAdvice" class="com.tarena.advice.LogAdvice"/>          <aop:config>              <aop:aspect id="logAspect" ref="logAdvice">                  <!-- 切入点 -->                  <aop:pointcut id="beforePointCut"               expression="execution(* saveUser*(..))"/>              <aop:pointcut id="afterPointCut"               expression="execution(* saveUser*(..))"/>                     <!-- 织入(通知作用于切入点) -->               <aop:before method="beforeLog" pointcut-ref="beforePointCut"/>              <aop:after method="afterLog" pointcut-ref="afterPointCut"/>              </aop:aspect>          </aop:config>  

测试类

    public class ActionTest {          public static void main(String[] args) {              ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");              IUserServ iuserServ = (IUserServ)ac.getBean("userServImpl");              iuserServ.deleteUserById(new User());              iuserServ.findAllUser();              iuserServ.saveUser(new User());          }      }  

运行结果

*执行删除方法*
*执行查询方法*
开始执行
*执行添加方法**
执行完毕

注:如果要在业务层所有的方法前后添加日志文件,则需要更改为以下配置

 <aop:pointcut id="beforePointCut"  expression="execution(* com.tarena.biz.*.*(..))"/>   <aop:pointcut id="afterPointCut"   expression="execution(* com.tarena.biz.*.*(..))"/> 

结果:

开始执行
*执行删除方法*
执行完毕
开始执行
*执行查询方法*
执行完毕
开始执行
*执行添加方法**
执行完毕

原文地址:http://blog.csdn.net/lirui0822/article/details/8555691

0 0
原创粉丝点击