• Spring_AOP


    切面(aspect)

    将横切多个业务对象的程序独立出来模块化,改模块可以无侵入式的集成到业务对象中,例如:事务、日志、权限

    通知(advice)

    通知是指切面的具体实现,如记录日志,权限验证

    通知有各种类型,其中包括:before、 after 、around和throw等通知

    连接点(joinPoint)

    通知执行的时机,如方法调用时,抛出异常等

    切入点(PointCut)

    切入点是感兴趣的连接点,通知和一个切入点表达式关联,并在满足这个切入点的链接点上运行,例如:当执行某个特定的名称方法

    切入点表达式如何和链接点匹配是AOP的核心:spring缺省使用AspectJ切入点语法。

    目标(Target)

    被一个或者多个切面所通知的对象,也有人把它叫做被通知对象,也可以是一个被代理的对象。

    AOP代理(AOP proxy)

    AOP框架创建的对象,用来实现切面的功能。在Spring中,AOP代理可以是JDK动态代理也可以是CGLIB代理。Spring 2.0最新引入的基于模式(schema-based)风格和@AspectJ注解风格的切面声明,对于使用这些风格的用户来说,代理的创建是透明的。

    织入(Weaving)

    把切面链接到其他应用程序类型或者对象上,并创建一个被通知的对象。Spring和其他纯Java AOP框架一样,在运行时完成织入。

    静态代理

    将系统中与业务逻辑无关的业务,由代理来完成。

    动态代理:

    在静态代理中,代理对象和被代理对象必须实现同一个接口。静态代理的弊端,一个代理接口只服务与一种类型的对象,系统庞大的时候代理会很多。

    动态代理:使用动态代理可以实现java中的java.lang.reflect.InvocationHandler接口(反射机制)

    该接口中的一个方法是:

    public Object invoke(Object proxy,Method method,Objrct[] args)

    proxy:代理对象

    method:代理管理方法

    args:方法的参数

    举例:打印日志的动态代理

    创建UserDao接口

    1 package com.feimao.proxy.test;
    2 
    3 public interface UserDao {
    4     public void delete(String name);
    5 }

    创建UserDao接口的实现类

     1 package com.feimao.proxy.test;
     2 
     3 import java.util.logging.Level;
     4 import java.util.logging.Logger;
     5 
     6 public class UserDaoImpl implements UserDao {
     7     //Logger logger = Logger.getLogger(this.getClass().getName());
     8     @Override
     9     public void delete(String name) {
    10         //logger.log(Level.INFO , "before delete");
    11         System.out.println("删除成功!");
    12         //logger.log(Level.INFO , "after delete");
    13     }
    14 
    15 }

    创建动态代理类

     1 package com.feimao.proxy.test;
     2 
     3 import java.lang.reflect.InvocationHandler;
     4 import java.lang.reflect.Method;
     5 import java.lang.reflect.Proxy;
     6 import java.util.logging.Level;
     7 import java.util.logging.Logger;
     8 
     9 public class DynamicLogProxy implements InvocationHandler{
    10     Object delegate;//Object是指代理所有对象,固定的类型只能代理一个
    11     Logger logger = Logger.getLogger(this.getClass().getName());
    12     public Object bind(Object delegate){
    13         this.delegate = delegate;
    14         Class cls = delegate.getClass();
    15         return Proxy.newProxyInstance(cls.getClassLoader() , cls.getInterfaces() , this);
    16     }
    17     public Object invoke(Object proxy , Method method , Object[] args)
    18         throws Throwable{
    19         logger.log(Level.INFO , "before delete");
    20         System.out.println(args[0]);
    21         Object retvalue = method.invoke(delegate , args);
    22         logger.log(Level.INFO , "after delete");
    23         return retvalue;
    24     }
    25 }

    创建测试类

     1 package com.feimao.proxy.test;
     2 
     3 public class Test {
     4     public static void main(String[] args){
     5        /* UserDao dao = new UserDaoImpl();
     6         dao.delete("feimao");*/
     7         UserDao dao = (UserDao) new DynamicLogProxy().bind(new UserDaoImpl());//强制类型转换
     8         dao.delete("feimao");
     9     }
    10 }

    运行结果:

    接下来我们再来代理下其他类,比如:代理顾客类

    创建CustomerDao接口

    1 package com.feimao.proxy.test;
    2 
    3 public interface CustomerDao {
    4     public String del(String name);
    5 
    6 }

    创建CustomerDaoImpl接口的实现类

    1 package com.feimao.proxy.test;
    2 
    3 public class CustomerDaoImpl implements CustomerDao {
    4     @Override
    5     public String del(String name) {
    6         System.out.println("delete ok …");
    7         return "zhubaobao";
    8     }
    9 }

    创建测试类

     1 package com.feimao.proxy.test;
     2 
     3 public class Test {
     4     public static void main(String[] args){
     5        /* UserDao dao = new UserDaoImpl();
     6         dao.delete("feimao");*/
     7         CustomerDao dao = (CustomerDao) new DynamicLogProxy().bind(new CustomerDaoImpl());//强制类型转换
     8         String str = dao.del("feimao");
     9         System.out.println(str);
    10     }
    11 }

    结果如下:

  • 相关阅读:
    js模板引擎v5
    js模板引擎v6
    python cookbook学习笔记[一次完成多个字符串的替换]
    您可能没注意到的ie6 select bug
    lambda参数写法问题
    python dict2种遍历方式及区别
    记一次 AXI id debug
    R2B fpga flow script
    axi 1.0
    advanced fpga design
  • 原文地址:https://www.cnblogs.com/feimaoyuzhubaobao/p/10034424.html
Copyright © 2020-2023  润新知