Spring代理模式及AOP

目录

一、代理模式

静态代理:

动态代理:

二、AOP

1.相关概念及意义:

2.使用Spring实现AOP

总结


一、代理模式

代理模式的好处

  • 可以使真实角色的操作更加纯粹!不用去关注一些公共的业务
  • 公共业务交给代理角色,从而实现业务的分工
  • 公共业务发生扩展时,方便集中管理
  • 代码耦合性降低

代理模式的缺点:

  • 一个真实角色就会产生一个代理角色,代码量会翻倍,开发效率变低

静态代理:

角色分析:

  • 抽象角色:一般会用接口或者抽象类来解决(例如租房 Rent)
  • 真实角色:被代理的角色(例如房东:Host)
  • 代理角色:代理真实角色,代理真实角色后,一般会做一些附属操作(例如租房中介)
  • 客户:访问代理对象的人(例如买房的人)

动态代理:

  • 动态代理和静态代理角色一样
  • 动态代理的代理类是动态生成的,不是我们直接写好的
  • 动态代理分为两大类:基于接口的动态代理,基于类的动态代理 
  • 基于接口——JOK动态代理
  • 基于类——cglib

实现步骤:①创造一个类继承InvacationHandler,用这个类自动生成代理类

                   代码如下(模板基本可直接套用,只需改接口名和接口中的方法名):

//用这个类自动生成代理类!
public class ProxyInvocationHandler implements InvocationHandler {

    //被代理的接口
    private UserService userService;
    //注意重写set方法
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    //生成得到代理类
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),userService.getClass().getInterfaces(),this);
    }

    //处理代理实例,并返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

    //动态代理的实质————反射机制
       Object result= method.invoke(userService,args);

        return result;
    }
}

                ②测试

    public static void main(String[] args) {
        
        //真实角色
        UserServiceImpl userService = new UserServiceImpl();
        
        //代理角色:现在没有
        ProxyInvocationHandler pih = new ProxyInvocationHandler();

        //通过调用程序处理角色来处理我们要调用的接口对象!
        pih.setUserService(userService);

        UserService proxy= (UserService) pih.getProxy();

        proxy.add();
    }

二、AOP

1.相关概念及意义:

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

  • 切面(Aspect):横切关注点 被模块化的特殊对象(即为一个类)
  • 通知(Advice):切面必须要完成的工作(即类中的方法)
  • 目标(Target):被通知的对象
  • 代理(Proxy):向目标对象应用通知之后创建的对象
  • 切入点(PointCut):切面通知执行的”地点“的定义
  • 连接点(JointPoint):与切入点匹配的执行点

意义:AOP是一种横向编程的思想,在不影响原来业务类的情况下,实现动态的增强

2.使用Spring实现AOP

【重点】使用AOP织入,需要先导入依赖包!

代码如下:

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
</dependency>

实现AOP的三种方式:

①使用Spring的API接口实现【主要是SpringAPI接口实现】

基本步骤:1、定义一个类(实现对应的前置增强或后置增强)

                       示例代码: 

public class log  implements MethodBeforeAdvice {


    public void before(Method method, Object[] args, Object target) throws Throwable {

        System.out.println(target.getClass().getName()+"的"+method.getName());
    }
    
}

                  2、将类注册到Spring中

                       示例代码:                                                       <!--  advice-ref指向对应增强类  -->

    <aop:config>
             <aop:pointcut id="pointcut" expression="execution(* service.UserServiceImpl.*(..))"/>
             
             <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
             <aop:advisor advice-ref="afterlog" pointcut-ref="pointcut"/>
    </aop:config>

                   3.测试

                      示例代码(下同,不再重复演示):

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("ApplicationContext.xml");

        UserService userService=(UserService) context.getBean("userService");
        userService.add();
    }
}

(注:动态代理代理的是接口,所以强转为UserService而不是UserServiceImpl)

②自定义来实现AOP【主要是切面定义】

基本步骤:1、自定义一个类,写方法用于增强

                  2、注册bean

示例代码:                  

<bean id="diy" class="diy.DiyPointCut"/>
    <aop:config>
        <!-- 自定义切面 ref为要引用的类 -->
        <aop:aspect ref="diy">
            <aop:pointcut id="point" expression="execution(* service.UserServiceImpl.*(..))"/>
            <aop:before method="before" pointcut-ref="point"/>
            <aop:after method="after" pointcut-ref="point"/>
        </aop:aspect>
    </aop:config>

<!-- method中引用的是定义的类中的方法,用于增强 -->

③使用注解实现

基本步骤:1、将所需增强的类前标注@Aspect  (标注这个类是一个切面)

                  2、在写增强方法之前,在方法前标注@Before("execution(省略)")等区别通知类型

                  3、配置文件,把增强类注册到bean中 (或直接在类前加@Configuration)

示例代码:

    <bean id="Aop" class="diy.aop"/>
        <aop:aspectj-autoproxy/>

总结

         记录Spring代理模式及AOP中的重点,方便以后复习巩固!

上一篇:简单的Spring IoC入门学习


下一篇:【施工中】Spring5