Spring学习笔记——AOP

静态代理和动态代理

静态代理:

角色:

1.抽象接口(租房:接口)

2.真实角色(比如房东小张:实现类实现抽象接口)

3.代理角色(代理真实角色,比如中介,负责帮小张卖方:实现类实现抽象接口,同时拥有小张这个成员属性,它可以调用小张实现的方法,并且增加自己的方法在里面)

4.客户(买房人:比如测试类,直接new 真实角色,并把真实角色传入new 代理角色中)

例子:

//抽象接口:租房
public interface Rent {
   public void rent();
}
//真实角色: 房东
public class Host implements Rent{
   public void rent() {
       System.out.println("房屋出租");
  }
}
//代理角色:中介
public class Proxy implements Rent {

   private Host host;
   public Proxy() { }
   public Proxy(Host host) {
       this.host = host;
  }

   //租房
   public void rent(){
       seeHouse();
       host.rent();
       fare();
  }
   //看房
   public void seeHouse(){
       System.out.println("带房客看房");
  }
   //收中介费
   public void fare(){
       System.out.println("收中介费");
  }
}
//客户类,一般客户都会去找代理!
public class Client {
   public static void main(String[] args) {
       //房东要租房
       Host host = new Host();
       //中介帮助房东
       Proxy proxy = new Proxy(host);

       //你去找中介!
       proxy.rent();
  }
}

核心思想:没有改变房东的代码,通过构造了新实现类中介,增强了房东的功能。对房东类进行了扩展。

即,我们在不改变原来的代码的情况下,实现了对原有功能的增强,这是AOP中最核心的思想

动态代理

在静态代理的例子中,Proxy类把房东小张作为成员变量,因此它只能代理小张(代码写死了)。如果存在其他房东也需要被代理,那对每个房东都需要写它的代理对象。因此引入动态代理,只需写一个代理对象,实现所有房东都能被代理。

动态代理分为两类 : 一类是基于接口动态代理 , 一类是基于类的动态代理:基于接口的动态代理----JDK动态代理,基于类的动态代理--cglib

两个关键类:InvocationHandler     和     Proxy

实现动态代理的步骤:

新建代理类继承InvocationHandler(把要代理的抽象接口作为属性传入),重写invoke方法。对该接口调用静态类Proxy.newProxyInstance()方法返回代理对象。

//抽象角色:租房
public interface Rent {
   public void rent();
}
//真实角色: 房东,房东要出租房子
public class Host implements Rent{
   public void rent() {
       System.out.println("房屋出租");
  }
}
public class ProxyInvocationHandler implements InvocationHandler {
   private Rent rent;

   public void setRent(Rent rent) {
       this.rent = rent;
  }

   //生成代理类,重点是第二个参数,获取要代理的抽象角色!之前都是一个角色,现在可以代理一类角色
   public Object getProxy(){
       return Proxy.newProxyInstance(this.getClass().getClassLoader(),
               rent.getClass().getInterfaces(),this);
  }

   // proxy : 代理类 method : 代理类的调用处理程序的方法对象.
   // 处理代理实例上的方法调用并返回结果
   @Override
   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       seeHouse();
       //核心:本质利用反射实现!
       Object result = method.invoke(rent, args);
       fare();
       return result;
  }

   //看房
   public void seeHouse(){
       System.out.println("带房客看房");
  }
   //收中介费
   public void fare(){
       System.out.println("收中介费");
  }

}
//租客
public class Client {

   public static void main(String[] args) {
       //真实角色
       Host host = new Host();
       //代理实例的调用处理程序
       ProxyInvocationHandler pih = new ProxyInvocationHandler();
       pih.setRent(host); //将真实角色放置进去!
       Rent proxy = (Rent)pih.getProxy(); //动态生成对应的代理类!
       proxy.rent();
  }

}

AOP方面

首先导入依赖


   org.aspectj
   aspectjweaver
   1.9.4

方式1:自己实现增强类(实现spring提供的接口) + xml配置       ——>见ref

方式2:自定义切入类 + xml配置       ——>见ref

方式3:注解

第一步:编写一个注解实现的增强类

package com.kuang.config;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class AnnotationPointcut {
   @Before("execution(* com.kuang.service.UserServiceImpl.*(..))")
   public void before(){
       System.out.println("---------方法执行前---------");
  }

   @After("execution(* com.kuang.service.UserServiceImpl.*(..))")
   public void after(){
       System.out.println("---------方法执行后---------");
  }

   @Around("execution(* com.kuang.service.UserServiceImpl.*(..))")
   public void around(ProceedingJoinPoint jp) throws Throwable {
       System.out.println("环绕前");
       System.out.println("签名:"+jp.getSignature());
       //执行目标方法proceed
       Object proceed = jp.proceed();
       System.out.println("环绕后");
       System.out.println(proceed);
  }
}

 

第二步:在Spring配置文件中,注册bean,并增加支持注解的配置



 

Reference:

狂神说公众号:https://www.bilibili.com/video/BV1WE411d7Dv

静态/动态代理模式:https://mp.weixin.qq.com/s/McxiyucxAQYPSOaJSUCCRQ

AOP就这么简单:https://mp.weixin.qq.com/s/zofgBRRrnEf17MiGZN8IJQ

 

你可能感兴趣的:(Spring,SSM,java)