年轻人,我观你骨骼精奇,定是万里无一的练武奇才,老夫这里有一本失传已久的武林秘籍,现赠于你,望你勤加苦练,早日修成正果...
AOP(面向切面编程):Aspect Oriented Programming
第一式、使用切面编程需要的配置
<aop:aspectj-autoproxyexpose-proxy="true"/>
开启切面编程功能,需要在applicationContext.xml文件中配置。
作用是:声明自动为spring容器中那些配置@aspectJ切面的bean创建代理,植入切面
第二式、切面编程
@Pointcut
放在方法头上,定义一个可被别的方法引用的切入点表达式。
Pointcut是Join Point(连接点)的集合,即它是程序中需要注入Advice(切入点上执行的行为)的位置的集合,指明Advice要在什么样的条件下才能被触发。
常用Pointcut表达式的讲解:execution(?com.glodon.gcxx.dao.hibimpl..(..)) ,这是com.glodon.gcxx.dao.hibimpl 包下所有的类的所有方法。
第一个代表所有的返回值类型 ,第二个代表所有的类, 第三个代表类所有方法 ,最后一个..代表所有的参数。
下面给出一些常见切入点表达式的例子。
1.任意公共方法的执行:execution(public * *(..)) 2.任何一个以“set”开始的方法的执行:execution(* set*(..)) 3.AccountService 接口的任意方法的执行:execution(* com.xyz.service.AccountService.*(..)) 4.定义在service包里的任意方法的执行:execution(* com.xyz.service.*.*(..)) 5.定义在service包或者子包里的任意类的任意方法的执行:execution(* com.xyz.service..*.*(..))?
<aop:config> <aop:aspectrefaop:aspectref="aspectDef"> <aop:pointcutidaop:pointcutid="pointcut1"expression="execution(* com.test.spring.aop.pointcutexp..JoinPointObjP2.*(..))"/> <aop:before pointcut-ref="pointcut1" method="beforeAdvice" /> </aop:aspect> </aop:config>?
@Component @Aspect public class AspectDef { //@Pointcut("execution(* com.test.spring.aop.pointcutexp..JoinPointObjP2.*(..))") //@Pointcut("within(com.test.spring.aop.pointcutexp..*)") //@Pointcut("this(com.test.spring.aop.pointcutexp.Intf)") //@Pointcut("target(com.test.spring.aop.pointcutexp.Intf)") //@Pointcut("@within(org.springframework.transaction.annotation.Transactional)") //@Pointcut("@annotation(org.springframework.transaction.annotation.Transactional)") @Pointcut("args(String)") public void pointcut1() { } @Before(value = "pointcut1()") public void beforeAdvice() { System.out.println("pointcut1 @Before..."); }?
第三式:主要应用场景
第四式:例子
首先在applicationContext.xml配置中配置:<aop:aspectj-autoproxy expose-proxy="true" />
1、使用execution定义pointcut方式
/** * 通过aop拦截后执行具体操作 * @author huangqw * */ @Aspect @Component public class LogIntercept { // com.glodon.action包下任意公共的(public)方法————解析切入点:public表示操作方法的权限,第一个*表示返回值,com.glodon.action表示报名,..表示子包,第二个*表示类,第三个*表示方法名称,(..)表示参数 @Pointcut(value="execution(public * com.glodon.action..*.*(..))") public void writeLog() { } <br>// 前置拦截,在执行目标方法之前的操作 @Before("writeLog()") public void before() { this.printLog("@Before 方法执行前——————做日志"); } // 环绕拦截,在执行目标方法的前后的操作 @Around("writeLog()") public void around(ProceedingJoinPoint pjp) throws Throwable { this.printLog("@Around 方法执行前——————做日志"); pjp.proceed(); this.printLog("@Around 方法执行后——————做日志"); } // 后置拦截,在执行目标方法之前的操作 @After("writeLog()") public void after() { this.printLog("@After 方法执行后——————做日志"); } private void printLog(String str) { System.out.println(str); } }?
/** * aop测试类 * @author huangqw */ @Controller public class TestAction { public void query() { System.out.println("查询操作"); } public static void main(String[] args) { @SuppressWarnings("resource") ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("resources/applicationContext.xml"); TestAction testAction = (TestAction) ctx.getBean("testAction"); testAction.query(); ctx.destroy(); } }?
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface AroundTest { String name() default "测试哈"; }?
@Component @Aspect public class AroundTestInteceptor { public AroundTestInteceptor(){ } /** * 定义切入点 */ @Pointcut(value="@annotation(com.glodon.around.AroundTest)") public void logAnnotatedMethod() { } /** * 拦截方法 * @param pjp * @return * @throws Throwable */ @Around("logAnnotatedMethod()") public Object inteceptorAction(ProceedingJoinPoint pjp) throws Throwable { Object o = null; MethodSignature joinPointObject = (MethodSignature) pjp.getSignature(); Method method = joinPointObject.getMethod(); boolean flag = method.isAnnotationPresent(AroundTest.class) ; if (flag) { AroundTest annotation = method.getAnnotation(AroundTest.class); Date enterDate = new Date(); System.out.println("开始执行方法:" + annotation.name()); //用于执行委托对象的目标方法 o = pjp.proceed(); Date leaveDate = new Date(); System.out.println("结束执行方法:"+ annotation.name() +",方法执行的时间:" + (leaveDate.getTime() - enterDate.getTime())); } return o; } }?
/** * aop测试类 * @author huangqw */ @Controller public class TestAction { @AroundTest(name="ceshi") public void query() { System.out.println("查询操作"); } public static void main(String[] args) { @SuppressWarnings("resource") ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("resources/applicationContext.xml"); TestAction testAction = (TestAction) ctx.getBean("testAction"); testAction.query(); ctx.destroy(); } }?
原文:http://843977358.iteye.com/blog/2264143