【sping揭秘】17、@Around,@Introduction
程序员文章站
2022-11-30 16:14:00
@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(); }
上一篇: 移动端事件