sping揭秘17@Around,@Introduction

Posted cutter_point

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sping揭秘17@Around,@Introduction相关的知识,希望对你有一定的参考价值。

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的主要内容,如果未能解决你的问题,请参考以下文章

sping揭秘12SpringAOP的实现机制

sping揭秘20spring的orm

sping揭秘25Spring远程方案

sping揭秘9容器内部事件发布

sping揭秘2关于spring配置文件

sping揭秘14@before @AfterThrowing