Spring学习系列--3.AOP

Spring Aop

Aop面向切面编程

Aop入门动态代理

动态代理,其实与Aop的原理有些相似,可以用动态代理来入门。

什么是动态代理

动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实。代理一般会实现它所表示的实际对象的接口。代理可以访问实际对,不允许直接访问某些类;对访问要做特殊处理客户隐藏了实际对象。客户不知道它是与代理打交道还是与实际对象打交道。

为什么使用动态代理

因为动态代理可以对请求进行任何处理,不允许直接访问某些类;对访问要做特殊处理等都需要使用动态代理进行解决。

动态代理Demo

public interface ISubject {

    void dosomething();
}

public class SubjectImpl implements ISubject {

    public void dosomething() {
        System.out.println("SubjectImpl is working....");

    }

}

public class SubjectLoggingProxy {

    private ISubject target;
    
    
    
    public SubjectLoggingProxy(ISubject target) {
        super();
        this.target = target;
    }



    public ISubject getLoggingProxy(){
        ISubject proxy= null;
        
        //代理对象由哪一个类加载器负责
        ClassLoader loader = target.getClass().getClassLoader();
        //代理对象类型
        Class[] interfaces = new Class[]{ISubject.class};
        //调用代理对象,其中的方法时,执行的代码
        InvocationHandler h = new InvocationHandler() {
            
            public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
                System.out.println(arg1.getName()+"proxy is working ...");
                
                arg1.invoke(target, arg2);
                return 0;
            }
        };
        proxy = (ISubject) Proxy.newProxyInstance(loader, interfaces, h);
        
        
        return proxy;
    }
}

public class Main {

    public static void main(String[] args) {
        ISubject target = new SubjectImpl();
        ISubject proxy = new SubjectLoggingProxy(target).getLoggingProxy();
        
        proxy.dosomething();
    }
}

Aop好处

  • 每个事物逻辑位于一个位置,代码不分散,便于维护和升级。
  • 业务模块更加简洁,只包含核心业务代码。

Aop术语

  • 切面 Aspect:横切关注点被模块化后的特殊对象
  • 通知 Advice:切面必须完成的方法
  • 目标 Target:被通知的对象
  • 代理 Proxy:向目标对象应用通知后创建的对象
  • 连接点 Joinpoint:程序执行的某个特定位置。类的方法的执行前,执行后等,有两个基本信息,1,方法, 2,相对点,那个方法执行前或后。
  • 切点 pointcut:

AspectJ 基于注解或xml实现AOP

@Aspect
@Component
public class LoggingAspect {

    @Before("execution(* spring.aop.impl.*.*(String))")
    public void beforeSay(JoinPoint joinPoint){
        List<Object> list = Arrays.asList(joinPoint.getArgs());
        System.out.println(list);
        System.out.println(" zhang zui..............");
        System.out.println(joinPoint.getSignature().getName());
    }
    
    @After("execution(* spring.aop.impl.*.*(String))")
    public void afterSay(){
        System.out.println(" bi zui..............");
    }
}
<context:component-scan base-package="spring.aop.impl"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

其他要点

  • @order(int) 可以标记切面的执行顺序
  • @Pointcut 来声明切入点表达式,后面的通知直接调用这个被它标记的方法。

基于xml

<!-- 配置AOP -->
<aop:config>
    <!-- 配置切点表达式 -->
    <aop:pointcut expression="execution(* spring.aop.xml.Subject.*(String))" id="pointcut"/>
    <!-- 配置切面及通知 -->
    <aop:aspect ref="loggingAspect" order="1">
        <aop:before method="beforeSay" pointcut-ref="pointcut"/>
    </aop:aspect>
</aop:config>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容