欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

【sping揭秘】17、@Around,@Introduction

程序员文章站 2022-05-07 19:09:19
@Introduction 我们先首先明确一点,这个注解是用来给原来的对象添加新的行为逻辑的 说白了就是给类扩展自定义方法 我们定义个类,作为添加方法的目标 好的,现在如果我们想给这个空的对象,添加一个,或者许多方法,怎么办呢??? 不急,我们先把要进行添加的方法准备好 这里是一个接口,里面有个do ......
package cn.cutter.start.bean;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;

/**
 * 
 * @author xiaof
 *
 */
@Component
public class AroundTestBean {
    
    private static final Log logger = LogFactory.getLog(AroundTestBean.class);

    
    public void method1() {
        logger.info("AroundTestBean 执行方法1");
    }
    
    public void method2(String param1) {
        logger.info("AroundTestBean 执行方法1" + param1);
    }
    
    public void method3() {
        logger.info("AroundTestBean 执行方法1");
    }
    
    public void method4() {
        logger.info("AroundTestBean 执行方法1");
    }
    
}

 

package cn.cutter.start.aop;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * 环绕拦截
 * @author xiaof
 *
 */
@Component
@Aspect
public class AroundAspect {

    private static final Log logger = LogFactory.getLog(AroundAspect.class);
    
    @Pointcut("execution(* cn.cutter.start.bean.AroundTestBean.method1(..))")
    public void pointcut1() {}
    
    @Pointcut("execution(* cn.cutter.start.bean.AroundTestBean.method2(..))")
    public void pointcut2() {}
    
    @Pointcut("execution(* cn.cutter.start.bean.AroundTestBean.method3(..))")
    public void pointcut3() {}
    
    @Pointcut("execution(* cn.cutter.start.bean.AroundTestBean.method4(..))")
    public void pointcut4() {}
    
    /**
     * 注意环绕拦截,必须有参数ProceedingJoinPoint joinPoint,而且必须是第一个
     * @param joinPoint
     */
    @Around("pointcut1()")
    public void around1(ProceedingJoinPoint joinPoint) {
        //环绕拦截,拦截 cn.cutter.start.bean.AroundTestBean.method1 这个方法
        try {
            logger.info("AroundAspect 环绕拦截的try中开始方法,然后执行对应的方法");
            Object o = joinPoint.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            logger.info("AroundAspect 环绕拦截的最终方法!");
        }
        
    }
    
    @Around("pointcut2() && args(taskName)")
    public void around2(ProceedingJoinPoint joinPoint, String taskName) {
        //环绕拦截,拦截 cn.cutter.start.bean.AroundTestBean.method1 这个方法
        try {
            logger.info("AroundAspect 环绕拦截的try中开始方法,然后执行对应的方法,参数是:" + taskName);
            Object o = joinPoint.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            logger.info("AroundAspect 环绕拦截的最终方法!");
        }
        
    }
    
    
}

 

@Test
    public void testAop6() {
        ApplicationContext ctx = this.before();
        
        AroundTestBean att = (AroundTestBean) ctx.getBean("aroundTestBean");
        
        att.method2("param test");
        
    }

 

@Introduction

 

我们先首先明确一点,这个注解是用来给原来的对象添加新的行为逻辑的

 

说白了就是给类扩展自定义方法

 

我们定义个类,作为添加方法的目标

 

package cn.cutter.start.bean;

import org.springframework.stereotype.Component;

@Component
public class IntroductionTestBean {

}

 

好的,现在如果我们想给这个空的对象,添加一个,或者许多方法,怎么办呢???

 

不急,我们先把要进行添加的方法准备好

package cn.cutter.start.introduction;

/**
 * 用来使用spring的扩展增强,@introduction
 * 用来给对象进行添加方法
 * @author xiaof
 *
 */
public interface TestIntroduction1 {
    
    public void dosomething();
    
}

这里是一个接口,里面有个dosomething的方法,我们可以实现多种方式,然后添加的效果也可以多种多样

 

我们实现两个类

 

package cn.cutter.start.introduction.impl;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import cn.cutter.start.introduction.TestIntroduction1;

public class TestIntroduction1Impl implements TestIntroduction1 {
    
    private final Log logger = LogFactory.getLog(TestIntroduction1Impl.class);

    @Override
    public void dosomething() {
        // TODO Auto-generated method stub
        logger.info("introduction 操作 dosomething!!!");
    }

}

 

package cn.cutter.start.introduction.impl;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import cn.cutter.start.introduction.TestIntroduction1;

public class TestIntroduction1Impl2 implements TestIntroduction1 {

    private final Log logger = LogFactory.getLog(TestIntroduction1Impl2.class);
    
    @Override
    public void dosomething() {
        logger.info("这里是另外一个实现接口的方法");

    }

}

好,要添加的目标有了,要添加的配料也有了,是时候炒一盘了

 

package cn.cutter.start.aop;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;
import org.springframework.stereotype.Component;

import cn.cutter.start.introduction.TestIntroduction1;
import cn.cutter.start.introduction.impl.TestIntroduction1Impl;
import cn.cutter.start.introduction.impl.TestIntroduction1Impl2;

@Component
@Aspect
public class IntroductionAspect {

    @DeclareParents(
            value="cn.cutter.start.bean.IntroductionTestBean",
            defaultImpl=TestIntroduction1Impl.class)
    public TestIntroduction1 testIntroduction1;
    
//    @DeclareParents(
//            value="cn.cutter.start.bean.IntroductionTestBean",
//            defaultImpl=TestIntroduction1Impl2.class)
//    public TestIntroduction1 testIntroduction2;
    
}

看到了么,这里@DeclareParents中的两个参数,一个是目标,一个是配置调料

 

Value是目标,defaultImpl是调料

 

测试一波:

@Test
    public void testAopIntroduction() {
        ApplicationContext ctx = this.before();
        
        IntroductionTestBean att = (IntroductionTestBean) ctx.getBean("introductionTestBean");
//        Object obj = (IntroductionTestBean) ctx.getBean("introductionTestBean");
        
        TestIntroduction1 test = (TestIntroduction1) att;
        test.dosomething();
//        
//        TestIntroduction1 test2 = (TestIntroduction1Impl2) obj;
//        test2.dosomething();
        
    }

 【sping揭秘】17、@Around,@Introduction