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(); }