Spring:动态代理及Aop

一.Proxy

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

1.静态代理

//代理角色
public class Proxy implements Rent {
    private Host host;

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

    public Proxy() {
    }

    public void rent() {
        lookHose();
        host.rent();
        contract();
        free();
    }
//看房
    public void lookHose() {
        System.out.println("看房");
    }
//签合同
    public void contract() {
        System.out.println("签合同");
    }
//收取中介费
    public void free() {
        System.out.println("收取中介费");
    }
}
//客户
public class Cilent {
    public static void main(String[] args) {
        //房东要租房子
        Host host = new Host();
        //中介代理帮租房子,但是一般会有一些会有一些附属操作
        Proxy proxy = new Proxy(host);
        //你不用面对房东,直接找中介租房即可
        proxy.rent();
    }
}

2.动态代理

//代理角色
public class ProxyInvocationHandle implements InvocationHandler {
    //获取代理的接口
    private Rent rent;

    public void setRent(Rent rent) {
        this.rent = rent;
    }
    //生成代理对象
    public Object getProx(){
 return  
     Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
    }
    //处理代理实例,并返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return method.invoke(rent,args);
    }
}
//客户
public class client {
    public static void main(String[] args) {
        //真实角色
        Host host = new Host();
        //代理角色
        ProxyInvocationHandle pri = new ProxyInvocationHandle();
        //设置要代理的对象(真实类)
        pri.setRent(host);
        //动态生成代理类
      Rent prox = (Rent) pri.getProx();
        prox.Rent();
    }
}

二.Aop

aop:面向切面编程,利用aop可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合性降低,提高程序的可重用性,同时提高了开发的效率

注:

  • 横切关注点:跨越应用程序多个模块的方法或功能,即,与我们业务逻辑无关,但是我们需要关注的部分,就是横切关注点。如日志,安全,缓存,事务等等
  • 切面(aspect):横切关注点被模块化的特殊对象,即----一个类
  • 通知(advice):切面必须要完成的工作。即----类中的一个方法
  • 目标(target):被通知的对象
  • 代理(Proxy):向目标对象引用通知之后创建的对象
  • 切入点(pointcut):切面通知执行的“地点”的定义
  • 连接点(jointPoint):与切入点匹配的执行点

Aop-eg:

//接口
public interface UserService {
    public void add();
    public void delete();
    public void update();
    public String select();
}
//实现类
@Component
public class UserServiceImpl implements UserService{
    public void add() {
        System.out.println("增加一条语句");
    }

    public void delete() {
        System.out.println("删除一条语句");
    }

    public void update() {
        System.out.println("更新一条语句");
    }

    public String select() {
        System.out.println("查询一条语句");
        return 2>3?"d":"c";
    }
}
//增加业务
@Component
public class Div {
     public void before(){
         System.out.println("执行前");
     }
     public void after(){
         System.out.println("执行后");
     }
}
配置文件
<!--第三种方法 注解-->
    <!--注解驱动-->
    <aop:aspectj-autoproxy/>

    <!--方式一:使用原生api接口-主要springAPI接口实现-->
    <!--配置aop-->
    <aop:config>
<!--切入点:expression:表达式,execution(要执行的位置!* * * * * *)-->
   <aop:pointcut id="pointcut" expression="execution(* com.zh.service.UserServiceImpl.*(..))"/>

        <!--执行环绕增加-->
        <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
    </aop:config>
    <!--方法二:自定义实现aop(切面定义)-->
    <aop:config>
        <!--自定义切面,ref-要引用的类-->
            <aop:aspect ref="div" >
                <!--切入点-->
                <aop:pointcut id="point" expression="execution(* com.zh.service.UserServiceImpl.*(..))"/>
           <!--通知-->
                <aop:after method="after" pointcut-ref="point"/>
                <aop:before method="before" pointcut-ref="point"/>
            </aop:aspect>
    </aop:config>
原文地址:https://www.cnblogs.com/zh93/p/12861230.html