zoukankan      html  css  js  c++  java
  • Spring AOP 自动创建代理

        Spring为我们提供了自动代理机制,让容器为我们自动生成代理,把我们从烦琐的配置工作中解放出来,在内部,Spring 使用BeanPostProcessor自动地完成这项工作。
     

    1、实现类介绍

        这些基于BeanPostProcessor的自动代理创建器的实现类,将根据一些规则自动在容器实例化Bean时为匹配的Bean生成代理实例。
        1)基于Bean配置名规则的自动代理创建器:允许为一组特定配置名的Bean自动创建代理实例的代理创建器,实现类为BeanNameAutoProxyCreator;
        2)基于Advisor匹配机制的自动代理创建器:它会对容器中所有的Advisor进行扫描,自动将这些切面应用到匹配的Bean中(即为目标Bean创建代理实例),实现类为DefaultAdvisorAutoProxyCreator;
        3)基于Bean中AspjectJ注解标签的自动代理创建器:为包含AspectJ注解的Bean自动创建代理实例,它的实现类是AnnotationAwareAspectJAutoProxyCreator,该类是Spring 2.0的新增类。
     
    2、BeanNameAutoProxyCreator
    Waiter业务类:
    package com.yyq.aop;
     
    public class Waiter {
        public void greetTo(String name) {
            System.out.println("waiter greet to " + name + ".");
        }
     
        public void serveTo(String name) {
            System.out.println("waiter serving to " + name + ".");
        }
    }

     Seller业务类:

    package com.yyq.aop;
     
    public class Seller {
        public void greetTo(String name) {
            System.out.println("seller greet to " + name + ".");
        }
    }

    GreetingBeforeAdvice前置增强实现类:

    package com.yyq.aop;
    import org.springframework.aop.MethodBeforeAdvice;
    import java.lang.reflect.Method;
     
    public class GreetingBeforeAdvice implements MethodBeforeAdvice {
        @Override
        public void before(Method method, Object[] objects, Object o) throws Throwable {
            System.out.println(o.getClass().getName() + "." + method.getName());
            String clientName = (String) objects[0];
            System.out.println("Hi! Mr." + clientName + ".");
        }
    }

    使用Bean名进行自动代理配置:

    <bean id="waiterTarget" class="com.yyq.aop.Waiter"/>
    <bean id="sellerTarget" class="com.yyq.aop.Seller"/>
    <bean id="greetingAdvice" class="com.yyq.aop.GreetingBeforeAdvice"/>
    <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"
           p:beanNames="*Target"
           p:interceptorNames="greetingAdvice"
           p:optimize="true"/>
        BeanNameAutoProxyCreator 有一个beanNames属性,它允许用户指定一组需要自动代理的Bean名称,Bean名称可以使用 * 通配符。
    测试方法:
    @Test
        public void testAdvisor6(){
            String configPath = "com\yyq\aop\beans.xml";
            ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);
            Waiter waiter = (Waiter)ctx.getBean("waiterTarget");
            Seller seller = (Seller)ctx.getBean("sellerTarget");
            waiter.greetTo("Peter");
            seller.greetTo("Tom");
        }

    输出结果:

    com.yyq.aop.Waiter.greetTo
    Hi! Mr.Peter.
    waiter greet to Peter.
    com.yyq.aop.Seller.greetTo
    Hi! Mr.Tom.
    seller greet to Tom.
     
    3、DefaultAdvisorAutoProxyCreator
        Advisor是切点和增强的复合体,Advisor本身已经包含了足够的信息:横切逻辑(要织入什么)以及连接点(织入到哪里)。DefaultAdvisorAutoProxyCreator能够扫描容器中的Advisor,并将Advisor自动织入到匹配的目标Bean中,即为匹配的目标Bean自动创建代理。
    配置:
    <bean id="waiterTarget" class="com.yyq.aop.Waiter"/>
    <bean id="sellerTarget" class="com.yyq.aop.Seller"/>
    <bean id="greetingAdvice" class="com.yyq.aop.GreetingBeforeAdvice"/>
    <bean id="regexpAdvisor2" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"
              p:pattern=".*greet.*"
              p:advice-ref="greetingAdvice"/>
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>

    测试方法:

    @Test
        public void testAdvisor7(){
            String configPath = "com\yyq\aop\beans.xml";
            ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);
            Waiter waiter = (Waiter)ctx.getBean("waiterTarget");
            Seller seller = (Seller)ctx.getBean("sellerTarget");
            waiter.greetTo("Peter");
            waiter.serveTo("Peter");
            seller.greetTo("Tom");
        }
    输出结果:
    com.yyq.aop.Waiter.greetTo
    Hi! Mr.Peter.
    waiter greet to Peter.
    waiter serving to Peter.
    com.yyq.aop.Seller.greetTo
    Hi! Mr.Tom.
    seller greet to Tom.
  • 相关阅读:
    image
    MySQLdb
    【基础】Equal方法、面向对象-多态-继承-封装
    【转】SSL协议、SET协议、HTTPS简介
    【转】UML图与软件开发过程那点关系
    【转载】日本社会为啥没有“王思聪”
    调用0A中断输入字符串数据段的DUP定义
    字符串输入逆序输出(回车换行符)
    输入单个字符并输出
    仿射密码加密解密文件流
  • 原文地址:https://www.cnblogs.com/yangyquin/p/5475664.html
Copyright © 2011-2022 走看看