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 }

结果如下:

原文地址:https://www.cnblogs.com/feimaoyuzhubaobao/p/10034424.html