Spring面向切面编程
==================================================
spring面向切面编程的方法之一:实现接口方式
1.执行前增强:MethodBeforeAdvice接口
标示方法:public void before(Method arg0, Object[] arg1, Object arg2){}
Method arg0----目标方法, Object[] arg1----方法中的参数, Object arg2----目标对象
2.执行后增强:AfterReturningAdvice接口
标示方法:public void afterReturning(Object arg0, Method arg1, Object[] arg2,Object arg3) throws Throwable {}
Object arg0-----返回值, Method arg1----目标方法, Object[] arg2----方法中的参数,Object arg3----目标对象
3.异常抛出时增强:ThrowAdvice接口
标示方法:public void afterThrowing(Method method, Object[] args, Object target,SQLException ex) {}
Method method----目标方法, Object[] args----方法中的参数, Object target----目标对象,SQLException ex------特定的异常对象,即该异常时才会使用增强方法
4.环绕增强:MethodInterceptor
标示方法:public Object invoke(MethodInvocation arg0) throws Throwable {}
Object target = arg0.getThis(); // 获取被代理对象
Method method = arg0.getMethod(); // 获取被代理方法
Object[] args = arg0.getArguments(); // 获取方法参数
Object result = arg0.proceed(); // 调用目标方法,获取目标方法返回值--------注意抛出异常,用来定义异常是的输出。
5.使用的是aop标签:定义bean用来指代特定的需调用的切面的类,后织入增强(定义切点以及增强)
<bean id="beforeAdvice" class="com.yunhe.aspect.BeforeAdvice"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.yunhe.biz.*.*(..))" id="pc1"/>
<aop:advisor advice-ref="beforeAdvice" pointcut-ref="pc1"/>
</aop:config>
==================================================
spring面向切面编程的方法之二:注解方式
1.使用@Aspect标示类,表明该类是使用注解是实现增强
2.执行前增强:@Before("execution(* biz.IUserBiz.*(..))")
标示方法:public void before() {}
3.执行后增强:@AfterReturning("execution(* biz.IUserBiz.*(..))")
标示方法:public void afterReturning() {}
4.异常抛出时增强:@AfterThrowing(pointcut = "execution(* biz.IUserBiz.*(..))", throwing = "e")
标示方法:public void afterThrowing(JoinPoint jp, RuntimeException e) {}
5.环绕增强:@Around("execution(* biz.IUserBiz.*(..))")
标示方法:public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable {}
6.最终增强:@After("execution(* biz.IUserBiz.*(..))")
标示方法:public void afterLogger(JoinPoint jp) {}
7.spring容器标示类的存在,使用aop标签在容器中表明使用注解方式进行增强
<bean class="aop.UserBizLogger"></bean>
<aop:aspectj-autoproxy />
8.JoinPoint jp的方法:
Object target = jp.getTarget(); // 获取被代理对象
Method method = jp.getSignature(); // 获取被代理方法
Object[] args = jp.getArgs(); // 获取方法参数,通常Arrays.toString(jp.getArgs())转化后用来输出参数表列
Object result = jp.proceed(); // 调用目标方法,获取目标方法返回值--------注意抛出异常,用来定义异常是的输出。
==================================================
spring面向切面编程的方法之三:Schema方式:普通JavaBean使用aop标签在容器中定义
1.前置增强:<aop:after>
标示方法:public void before(JoinPoint jp) {}
2.后置增强:<aop:after-returning>
标示方法:public void afterReturning(JoinPoint jp, Object result) {}
3.异常抛出时增强:<aop:after-throwing>
标示方法:public void afterThrowing(JoinPoint jp, RuntimeException e) {}
4.环绕增强:<aop:around>
标示方法: public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable {}
5.最终增强:<aop:aspect>
标示方法:public void afterLogger(JoinPoint jp) {}
6.定义增强类,织入(定义切点,织入)
<bean id="theLogger" class="aop. AfterLogger"></bean>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* biz.IUserBiz.*(..))" />
<aop:aspect ref="theLogger">
<aop:after method="afterLogger" pointcut-ref="pointcut" />
</aop:aspect>
</aop:config>
Aop切面编程的几个例子
==================================================
例一:log4j实现记录日志---接口
1.实现方式:利用实现接口的Aop方法给特定方法执行后置增强
2.步骤:添加log4j.properties在src下,以及log4j-1.2.17.jar添加lib下
3.实现类实现接口用来定义
public class AfterAdvice implements AfterReturningAdvice {
Logger logger = Logger.getLogger(AfterAdvice.class);
public void afterReturning(Object arg0, Method arg1, Object[] arg2,
Object arg3) throws Throwable {
// TODO Auto-generated method stub
logger.debug("后置:执行对象:" + arg3 + "的方法为:" + arg1.getName() );
}
}
4.Spring容器中定义切入方式(一个点多个面,一个面多个点均可)
<bean id="beforeAdvice" class="com.yunhe.aspect.BeforeAdvice"></bean>
<bean id="afterAdvice" class="com.yunhe.aspect.AfterAdvice"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.yunhe.biz.*.*(..))" id="pc1"/>
<aop:advisor advice-ref="beforeAdvice" pointcut-ref="pc1"/>
<aop:advisor advice-ref="afterAdvice" pointcut-ref="pc1"/>
</aop:config>
5.log4j.properties的配置文件信息
1. ### ÉèÖÃLoggerÊä³ö¼¶±ðºÍÊä³öÄ¿µÄµØ ###
2. log4j.rootLogger=debug, stdout,logfile
3.
4. ### °ÑÈÕÖ¾ÐÅÏ¢Êä³öµ½¿ØÖÆ̨ ###
5. log4j.appender.stdout=org.apache.log4j.ConsoleAppender
6. log4j.appender.stdout.Target=System.err
7. log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
8.
9. ### °ÑÈÕÖ¾ÐÅÏ¢Êä³öµ½Îļþ£ºjbit.log ###
10. log4j.appender.logfile=org.apache.log4j.FileAppender
11. log4j.appender.logfile.File=jbit.log
12. log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
13. log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %l %F %p %m%n
6.
==================================================
例二:环绕增强---接口
1.实现方式:利用实现接口的Aop方法给特定方法执行环绕增强,并在产生异常的情况下进行提示
2.步骤:添加log4j.properties在src下,以及log4j-1.2.17.jar添加lib下
3.实现类实现接口用来定义
1. public class AroundLogger implements MethodInterceptor {
2. private static final Logger log = Logger.getLogger(AroundLogger.class);
3.
4. public Object invoke(MethodInvocation arg0) throws Throwable {
5. Object target = arg0.getThis(); // 获取被代理对象
6. Method method = arg0.getMethod(); // 获取被代理方法
7. Object[] args = arg0.getArguments(); // 获取方法参数
8. log.info("调用 " + target + " 的 " + method.getName() + " 方法。方法入参:"
9. + Arrays.toString(args));
10. try {
11. Object result = arg0.proceed(); // 调用目标方法,获取目标方法返回值
12. log.info("调用 " + target + " 的 " + method.getName() + " 方法。方法返回值:"
13. + result);
14. return result;
15. } catch (Throwable e) {
16. log.error(method.getName() + " 方法发生异常:" + e);
17. throw e;
18. }
19. }
20. }
4.Spring容器配置
1. <bean id="aroundLogger" class="aop.AroundLogger"></bean>
2. <aop:config>
3. <aop:pointcut id="pointcut" expression="execution(* biz.IUserBiz.*(..))" />
4. <aop:advisor pointcut-ref="pointcut" advice-ref="aroundLogger" />
5. </aop:config>
==================================================
例三:特定异常增强---注解
1.使用注解的Aop方式实现异常增强
2.方法中
1. @Aspect
2. public class ErrorLogger {
3. private static final Logger log = Logger.getLogger(ErrorLogger.class);
4. @AfterThrowing(pointcut = "execution(* biz.IUserBiz.*(..))", throwing = "e")
5. public void afterThrowing(JoinPoint jp, RuntimeException e) {
6. log.error(jp.getSignature().getName() + " 方法发生异常:" + e);
7. }
8. }
3.Spring容器配置
<bean class="aop.ErrorLogger"></bean>
<aop:aspectj-autoproxy />
==================================================
例四:环绕增强---注解
1.使用注解方式实现环绕增强
2.
1. @Aspect
2. public class AroundLogger {
3. private static final Logger log = Logger.getLogger(AroundLogger.class);
4. @Around("execution(* biz.IUserBiz.*(..))")
5. public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable {
6. log.info("调用 " + jp.getTarget() + " 的 " + jp.getSignature().getName()
7. + " 方法。方法入参:" + Arrays.toString(jp.getArgs()));
8. try { Object result = jp.proceed();
9. log.info("调用 " + jp.getTarget() + " 的 "
10. + jp.getSignature().getName() + " 方法。方法返回值:" + result);
11. return result;
12. } catch (Throwable e) {
13. log.error(jp.getSignature().getName() + " 方法发生异常:" + e);
14. throw e; }
15. } }
3.注解方式的前置后置以及最终增强类型
1. @Aspect
2. public class AfterLogger {
3. private static final Logger log = Logger.getLogger(AfterLogger.class);
4. @After("execution(* biz.IUserBiz.*(..))")
5. public void afterLogger(JoinPoint jp) {
6. log.info(jp.getSignature().getName() + " 方法结束执行。");
7. }
8. }
1. @Aspect
2. public class UserBizLogger {
3. private static final Logger log = Logger.getLogger(UserBizLogger.class);
4.
5. @Before("execution(* biz.IUserBiz.*(..))")
6. public void before() {
7. log.info("即将调用业务方法");
8. }
9.
10. @AfterReturning("execution(* biz.IUserBiz.*(..))")
11. public void afterReturning() {
12. log.info("业务方法调用完毕");
13. }
14.
15. }
==================================================
例五:环绕增强-----schema方式
1.使用注解方式实现环绕增强
1. public class AroundLogger {
2. public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable { … }
3. }
1. <bean id="theLogger" class="aop. AroundLogger"></bean>
2. <aop:config>
3. <aop:pointcut id="pointcut" expression="execution(* biz.IUserBiz.*(..))" />
4. <aop:aspect ref="theLogger">
5. <aop:around method="aroundLogger" pointcut-ref="pointcut" />
6. </aop:aspect>
7. </aop:config>
==================================================
例六:最终增强-----schema方式
1. public class AfterLogger {
2. public void afterLogger(JoinPoint jp) { … }
3. }
1. <bean id="theLogger" class="aop. AfterLogger"></bean>
2. <aop:config>
3. <aop:pointcut id="pointcut" expression="execution(* biz.IUserBiz.*(..))" />
4. <aop:aspect ref="theLogger">
5. <aop:after method="afterLogger" pointcut-ref="pointcut" />
6. </aop:aspect>
7. </aop:config>