标签:style blog http io ar color 使用 sp for
一、XML配置方式
1.创建一个Service类
package com.spring.useage.service; public class UserService { public void save() { System.out.println("save a user."); } public void findById(String id) { System.out.println("find a user by id"); } public void deleteUser() { System.out.println("a user is deleted."); } }
2.创建一个切面类
package com.spring.aop; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.aspectj.lang.JoinPoint; public class SecurityCheck { public final static Log log = LogFactory.getLog(SecurityCheck.class); public void check() { log.info("权限校验。。。"); } public void addLog(JoinPoint joinPoint) { log.info("添加日志。。。"); String methodName = joinPoint.getSignature().getName(); log.info("方法名:" + methodName); log.info("方法参数:"); Object[] args = joinPoint.getArgs(); for (Object obj : args) { log.info(obj); } } }
3.XML配置的方式如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <bean id="securityCheck" class="com.spring.aop.SecurityCheck"></bean> <bean id="userService" class="com.spring.useage.service.UserService"></bean> <aop:config> <aop:aspect id="myAop" ref="securityCheck"> <aop:pointcut id="target" expression="execution(* com.spring.useage.service.*.*(..))" /> <aop:before method="check" pointcut-ref="target" /> <aop:after method="addLog" pointcut-ref="target" /> </aop:aspect> </aop:config> </beans>
execution(* com.spring.useage.service.*.*(..))说明:
第1个*:表示所有返回值类型
第2个*:表示com.spring.useage.service下的所有类
第3个*:表示所有方法
最后的..:表示任意参数
需要引入的包如下:
4.测试类如下:
package com.spring.aop; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.spring.useage.service.UserService; public class AopTest { /** * * @author qincd * @date Nov 24, 2014 6:30:00 PM */ public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); UserService us = ac.getBean(UserService.class); us.save(); us.findById("admin"); us.deleteUser(); } }
执行AopTest,输出如下:
2014-11-25 9:59:10 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@14d3343: startup date [Tue Nov 25 09:59:10 CST 2014]; root of context hierarchy
2014-11-25 9:59:10 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
2014-11-25 9:59:10 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1b3f829: defining beans [securityCheck,userService,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.aop.aspectj.AspectJPointcutAdvisor#0,org.springframework.aop.aspectj.AspectJPointcutAdvisor#1,target]; root of factory hierarchy
2014-11-25 9:59:10 com.spring.aop.SecurityCheck check
信息: 权限校验。。。
save a user.
2014-11-25 9:59:10 com.spring.aop.SecurityCheck addLog
信息: 添加日志。。。
2014-11-25 9:59:10 com.spring.aop.SecurityCheck addLog
信息: 方法名:save
2014-11-25 9:59:10 com.spring.aop.SecurityCheck addLog
信息: 方法参数:
2014-11-25 9:59:10 com.spring.aop.SecurityCheck check
信息: 权限校验。。。
find a user by id
2014-11-25 9:59:10 com.spring.aop.SecurityCheck addLog
信息: 添加日志。。。
2014-11-25 9:59:10 com.spring.aop.SecurityCheck addLog
信息: 方法名:findById
2014-11-25 9:59:10 com.spring.aop.SecurityCheck addLog
信息: 方法参数:
2014-11-25 9:59:10 com.spring.aop.SecurityCheck addLog
信息: admin
2014-11-25 9:59:10 com.spring.aop.SecurityCheck check
信息: 权限校验。。。
a user is deleted.
2014-11-25 9:59:10 com.spring.aop.SecurityCheck addLog
信息: 添加日志。。。
2014-11-25 9:59:10 com.spring.aop.SecurityCheck addLog
信息: 方法名:deleteUser
2014-11-25 9:59:10 com.spring.aop.SecurityCheck addLog
信息: 方法参数:
二、Annotation方式
1.UserService类加上@Service注解
package com.spring.useage.service; import org.springframework.stereotype.Service; @Service public class UserService { public void save() { System.out.println("save a user."); } public void findById(String id) { System.out.println("find a user by id"); } public void deleteUser() { System.out.println("a user is deleted."); } }
2.SecurityCheck加上@Aspect和@Component注解
package com.spring.aop; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; @Aspect @Component public class SecurityCheck { public final static Log log = LogFactory.getLog(SecurityCheck.class); @Before("execution (* com.spring.**.service.*.*(..))") public void check() { log.info("权限校验。。。"); } @After("execution (* com.spring.**.service.*.*(..))") public void addLog(JoinPoint joinPoint) { log.info("添加日志。。。"); String methodName = joinPoint.getSignature().getName(); log.info("方法名:" + methodName); log.info("方法参数:"); Object[] args = joinPoint.getArgs(); for (Object obj : args) { log.info(obj); } } }
1、@Aspect:意思是这个类为切面类
2、@Componet:因为作为切面类需要Spring管理起来,所以在初始化时就需要将这个类初始化加入Spring的管理;
3、@Befoe:切入点的逻辑(Advice)
4、execution…:切入点语法
applicationContext.xml加入aspectj自动代理,并启用注解。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <aop:aspectj-autoproxy /> <context:annotation-config /> <context:component-scan base-package="com.spring" /> </beans>
当多个Advice个有相同的织入点。那么我们可以定义一个织入点集合,在需要使用的地方,调用就可以了。
如:
package com.spring.aop; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; @Aspect @Component public class SecurityCheck { public final static Log log = LogFactory.getLog(SecurityCheck.class); @Before("myPointCut()") public void check() { log.info("权限校验。。。"); } @After("myPointCut()") public void addLog(JoinPoint joinPoint) { log.info("添加日志。。。"); String methodName = joinPoint.getSignature().getName(); log.info("方法名:" + methodName); log.info("方法参数:"); Object[] args = joinPoint.getArgs(); for (Object obj : args) { log.info(obj); } } @AfterReturning("myPointCut()") public void afterReturning() { log.info("method after returning..."); } @Around("myPointCut()") public void around(ProceedingJoinPoint pjp) throws Throwable { log.info("method around start..."); pjp.proceed(); log.info("method around end..."); } @AfterThrowing("myPointCut()") public void afterThrowing(JoinPoint joinPoint) { log.error(joinPoint.getSignature().getName() + "执行异常:" ); } @Pointcut("execution (* com.spring..service.*.*(..))") public void myPointCut() {} }
注意:那个空方法,只是为了给Pointcut起个名字,以方便别处使用
AOP实现动态代理注意
因为Spring要实现AOP(面向切面编程),需要加入切面逻辑的类就会生成动态代理。在动态代理类中加入切面类从而实现面向切面编程,但生成动态代理存在以下注意事项:
1、 被动态代理的类如果实现了某一个接口,那么Spring就会利用JDK类库生成动态代理。
2、 如果被动态代理的类没有实现某一个接口,那么Spring就会利用CGLIB类库直接修改二进制码来生成动态代理(因为利用JDK生成动态代理的类必须实现一个接口),需要在项目中引用CGLIB类库
参考:http://blog.csdn.net/yuqinying112/article/details/7335416
标签:style blog http io ar color 使用 sp for
原文地址:http://www.cnblogs.com/luckystar2010/p/4120410.html