zoukankan      html  css  js  c++  java
  • Spring第四天

    顾问包装通知

    通知(advice)是Spring中的一种比较简单的切面,只能将切面织入到目标类的所有方法中,而无法对指定方法进行增强 顾问(advisor)是Spring提供的另外一种切面,可以织入到指定的方法中  接口 PointcutAdvisor

    实现类:NameMatchMethodPointcutAdvisor(基于方法名称的增强顾问),RegexpMethodPointcutAdvice(基于正则表达式的增强顾问)

    新增advisor包,实现顾问的测试用例

    新建app-02.xml文件,内容如下

    <!--将目标对象声明到Spring容器中-->
    <bean id="doSomeService" class="com.cmy.service.impl.DoSomeServiceImpl"></bean>
    
    <!--将advice声明到容器中-->
    <bean id="advice" class="com.cmy.CodeAdvice.BeforeAndAfter"></bean>
    
    <!--配置顾问:包装通知-->
    <bean id="advisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
          <property name="advice" ref="advice"></property>
          <!--指定为say方法实现增强-->
          <property name="mappedName" value="say"></property>
    </bean>
    
    <!--配置代理工厂-->
    <bean id="proxyfactory" class="org.springframework.aop.framework.ProxyFactoryBean">
           <property name="target" ref="doSomeService"></property>
           <!--将通知替换成为顾问-->
           <property name="interceptorNames" value="advisor"></property>
    </bean>

    以上文件使用的是NameMatchMethodPointcutAdvisor,当然也可替换成为 RegExpMethodPonitcutAdvisor,基于正则表达式通配方法名的顾问,可配置性更加优良。

    <bean id="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
           <property name="advice" ref="advice"></property>
           <!--指定为带say的函数进行增强-->
           <property name="pattern" value=".*say.*"></property>
    </bean>

    顾问代理生成器

        顾问代理生成器,当我们声明好顾问后为目标对象生成代理对象。如果项目中 存在多个代理对象的话,需要实例化许多的ProxyFactoryBean,我们可以使用顾 问 代理生成器来解决这个问题。  

            顾问代理生成器主要分两种

          自动顾问代理生成器:DefaultAdvisorAutoProxyCreator

          名称顾问代理生成器:BeanNameAutoProxyCreator

      继续使用advisor包,创建app-03.xml文件,新增顾问代理生成器

    --将目标对象声明到Spring容器中-->
    <bean id="doSomeService" class="com.cmy.service.impl.DoSomeServiceImpl"></bean>
    <!--将advice声明到容器中-->
    <bean id="advice" class="com.cmy.CodeAdvice.BeforeAndAfter"></bean>
    <!--顾问包装通知-->
    <bean id="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
           <property name="advice" ref="advice"></property>
           <!--指定为带say的函数进行增强-->
           <property name="pattern" value=".*say.*"></property>
    </bean>
    
    <!--名称顾问代理生成器:需要指定被代理的目标对象和顾问名-->
    <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
           <property name="beanNames" value="doSomeService"></property>
           <property name="interceptorNames" value="advisor"></property>
    </bean>

    创建测试用例

    public class Demo2 {
        public static void main(String[] args) {
            //声明式增强 必须加载Spring容器
            ApplicationContext app = new ClassPathXmlApplicationContext("com/cmy/advisor/app-03.xml");
            //在Spring容器中已直接为DoSomeService创建好了代理对象 无需创建代理工厂
            DoSomeService doSomeService=(DoSomeService)app.getBean("doSomeService");
            doSomeService.say();
        }
    }

    IOC和DI的注解

          IOC:

                              @Component:实现Bean组件的定义

                              @Repository:用于标注DAO类,功能与@Component作用相当

                              @Service:用于标注业务类

                              @Controller:用于标注控制器

                  DI:

                              @Resource(name="userService")

                                   默认ByName方式,如果name确实默认按照ByType方式注入

                              @Autowired

                                  默认ByType方式,如果出现同名类,则不能按照Type进行注入

                                需要使用@Qualifier 指明ID

    使用注解方式实现Spring AOP   

    实现AOP的注解有

    @Aspect 声明切面

    @Ponitcut 声明公共的切点表达式

    @Before 前置增强

    @AfterReturning 后置增强

    @Around 环绕增强

    @AfterThrowing 异常抛出增强

    @After 最终增强

    使用注解实现前置+后置增强

    /**
     * 使用注解定义切面
     */
    @Aspect
    public class UserServiceLogger {
       @Pointcut("execution(* com.cmy.service.*.*(..))")
       public void pointcut() {}
       
       @Before("pointcut()")
       public void before(JoinPoint jp) {
          System.out.println("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
                + " 方法。方法入参:" + Arrays.toString(jp.getArgs()));
       }
       @AfterReturning(pointcut = "pointcut()", returning = "returnValue")
       public void afterReturning(JoinPoint jp, Object returnValue) {
          System.out.println("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
                + " 方法。方法返回值:" + returnValue);
       }
    }

    创建Spring的核心配置文件,开启Spring对IOC和AOP注解的支持

    新增app-07.xml文件

    <!--开启Spring IOC的注解支持 base-package 包扫描语句 com.cmy包下的注解-->
    <context:component-scan base-package="com.cmy"/>
    <!--配置增强类 交给Spring容器管理-->
    <bean class="com.cmy.AfterAndBefore.UserServiceLogger"></bean>
    <!--开启Spring AOP注解的支持-->
    <aop:aspectj-autoproxy />

    service包下给DoSomeServiceImpl声明@Service注解

    Service("doSomeService")//与<bean id="doSomeService" class="XXX">相同
    public class DoSomeServiceImpl implements DoSomeService {
    
        @Override
        public void say() {
            //int result=5/0;
            System.out.println("呵呵");
        }
    }

    测试类

    public class Demo {
        public static void main(String[] args) {
            //声明式增强 必须加载Spring容器
            ApplicationContext app = new ClassPathXmlApplicationContext("com/cmy/AfterAndBefore/app-07.xml");
            //获取代理对象
            DoSomeService doSomeService=(DoSomeService)app.getBean("doSomeService");
            doSomeService.say();
        }
    }
  • 相关阅读:
    Jconsole连接远程服务器
    limesurvey设置短调查问卷url
    centos7 安装R和Rstudio客户端
    p便签,去掉首行缩进
    linux mint运行docker
    Kafka高可用实现
    利用ZooKeeper简单实现分布式锁
    如何判断一个数是否在40亿个整数中?
    稀疏矩阵乘法
    Java 软引用和弱引用
  • 原文地址:https://www.cnblogs.com/ws1149939228/p/11777177.html
Copyright © 2011-2022 走看看