Spring使用AspectJ注解和XML配置实现AOP
本文演示的是Spring中使用AspectJ注解和XML配置两种方式实现AOP
下面是使用AspectJ注解实现AOP的JavaProject
首先是位于classpath下的applicationContext.xml文件
<?xmlversion="1.0"encoding="UTF-8"?> <beansxmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!--启用AspectJ对Annotation的支持--> <aop:aspectj-autoproxy/> <beanid="userManager"class="com.jadyer.annotation.UserManagerImpl"/> <beanid="securityHandler"class="com.jadyer.annotation.SecurityHandler"/> </beans>
然后是服务层接口以及实现类
packagecom.jadyer.annotation;
publicinterfaceUserManager{
publicvoidaddUser(Stringusername,Stringpassword);
publicvoiddelUser(intuserId);
publicStringfindUserById(intuserId);
publicvoidmodifyUser(intuserId,Stringusername,Stringpassword);
}
/**
*上面的UserManager是服务层的接口
*下面的UserManagerImpl是服务层接口的实现类
*/
packagecom.jadyer.annotation;
publicclassUserManagerImplimplementsUserManager{
publicvoidaddUser(Stringusername,Stringpassword){
System.out.println("------UserManagerImpl.addUser()isinvoked------");
}
publicvoiddelUser(intuserId){
System.out.println("------UserManagerImpl.delUser()isinvoked------");
}
publicStringfindUserById(intuserId){
System.out.println("------UserManagerImpl.findUserById()isinvoked------");
return"铁面生";
}
publicvoidmodifyUser(intuserId,Stringusername,Stringpassword){
System.out.println("------UserManagerImpl.modifyUser()isinvoked------");
}
}
接下来是使用AspectJ注解标注的切入类
packagecom.jadyer.annotation;
importorg.aspectj.lang.annotation.After;
importorg.aspectj.lang.annotation.Aspect;
importorg.aspectj.lang.annotation.Pointcut;
@Aspect
publicclassSecurityHandler{
/**
*定义Pointcut
*@seePointcut的名称为addAddMethod(),此方法没有返回值和参数
*@see该方法就是一个标识,不进行调用
*/
@Pointcut("execution(*add*(..))")//匹配所有以add开头的方法
privatevoidaddAddMethod(){};
/**
*定义Advice
*@see表示我们的Advice应用到哪些Pointcut订阅的Joinpoint上
*/
//@Before("addAddMethod()")
@After("addAddMethod()")
privatevoidcheckSecurity(){
System.out.println("------【checkSecurityisinvoked】------");
}
}
最后是客户端测试类
packagecom.jadyer.annotation;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.support.ClassPathXmlApplicationContext;
/**
*Spring对AOP的支持:采用Annotation方式
*@see-------------------------------------------------------------------------------------
*@seeSpring提供的AOP功能还是很强大的,支持可配置,它的默认实现使用的就是JDK动态代理
*@see使用Spring的AOP不需要继承相关的东西,也不需要实现接口
*@see但有个前提条件:由于是JDK动态代理,所以若想生成代理,该类就必须得实现一个接口才行
*@see如果该类没有implements接口的话,仍去使用Spring的默认AOP实现时,那么就会出错
*@see通常需要生成代理的类都是服务层的类,所以通常都会抽一个接口出来。即养成面向接口编程的习惯
*@see-------------------------------------------------------------------------------------
*@see采用Annotation方式完成AOP示例的基本步骤,如下
*@see1、Spring2.0的依赖包配置。新增Annotation支持
*@see*SPRING_HOME//dist//spring.jar
*@see*SPRING_HOME//lib//log4j//log4j-1.2.14.jar
*@see*SPRING_HOME//lib//jakarta-commons//commons-logging.jar
*@see*SPRING_HOME//lib//aspectj//*.jar
*@see2、将横切性关注点模块化,建立SecurityHandler.java
*@see3、采用注解指定SecurityHandler为Aspect
*@see4、采用注解定义Advice和Pointcut
*@see5、启用AspectJ对Annotation的支持,并且将目标类和Aspect类配置到IoC容器中
*@see6、开发客户端
*@see-------------------------------------------------------------------------------------
*/
publicclassClient{
publicstaticvoidmain(String[]args){
ApplicationContextfactory=newClassPathXmlApplicationContext("applicationContext.xml");
UserManageruserManager=(UserManager)factory.getBean("userManager");
userManager.addUser("张起灵","02200059");
}
}
下面是使用XML配置文件实现AOP的JavaProject
首先是位于src根目录中的applicationContext-cglib.xml文件
<?xmlversion="1.0"encoding="UTF-8"?> <beansxmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!--强制使用CGLIB代理--> <!--<aop:aspectj-autoproxyproxy-target-class="true"/>--> <beanid="userManager"class="com.jadyer.cglib.UserManagerImpl"/> <beanid="securityHandler"class="com.jadyer.cglib.SecurityHandler"/> <aop:config> <aop:aspectid="securityAspect"ref="securityHandler"> <aop:pointcutid="addAddMethod"expression="execution(*add*(..))"/> <aop:beforemethod="checkSecurity"pointcut-ref="addAddMethod"/> </aop:aspect> </aop:config> </beans> <!-- 匹配add开头的所有的方法 execution(*add*(..)) 匹配com.jadyer.servcices.impl包下的所有的类的所有的方法 execution(*com.jadyer.servcices.impl.*.*(..)) 匹配com.jadyer.servcices.impl包下的add或者del开头的所有的方法 execution(*com.jadyer.servcices.impl.*.add*(..))||execution(*com.jadyer.servcices.impl.*.del*(..)) -->
然后是服务层接口以及实现类
packagecom.jadyer.cglib;
publicinterfaceUserManager{
publicvoidaddUser(Stringusername,Stringpassword);
publicvoiddelUser(intuserId);
publicStringfindUserById(intuserId);
publicvoidmodifyUser(intuserId,Stringusername,Stringpassword);
}
/**
*上面的UserManager是服务层接口
*下面的UserManagerImpl是服务层接口的实现类
*/
packagecom.jadyer.cglib;
publicclassUserManagerImpl{
//implementsUserManager{
publicvoidaddUser(Stringusername,Stringpassword){
System.out.println("------UserManagerImpl.addUser()isinvoked------");
}
publicvoiddelUser(intuserId){
System.out.println("------UserManagerImpl.delUser()isinvoked------");
}
publicStringfindUserById(intuserId){
System.out.println("------UserManagerImpl.findUserById()isinvoked------");
return"张三";
}
publicvoidmodifyUser(intuserId,Stringusername,Stringpassword){
System.out.println("------UserManagerImpl.modifyUser()isinvoked------");
}
}
接着是在applicationContext-cglib.xml中所指定的切入类
packagecom.jadyer.cglib;
importorg.aspectj.lang.JoinPoint;
/**
*将客户调用信息传递到该Advice中
*@see可以在Advice中添加一个JoinPoint参数,取得客户端调用的方法名称及参数值
*@see以后纯粹使用AOP去写类似这样东西的情况比较少,我们主要使用Spring提供的事务
*@see关于这个,知道即可。下面是示例代码
*/
publicclassSecurityHandler{
privatevoidcheckSecurity(JoinPointjoinPoint){
for(inti=0;i<joinPoint.getArgs().length;i++){
System.out.println(joinPoint.getArgs()[i]);//获取客户端调用的方法的参数值
}
System.out.println(joinPoint.getSignature().getName());//获取客户端调用的方法名称
System.out.println("------【checkSecurityisinvoked】------");
}
}
最后是客户端测试类
packagecom.jadyer.cglib;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.support.ClassPathXmlApplicationContext;
/**
*@see--------------------------------------------------------------------------------------------------
*@seeJDK动态代理和CGLIB代理的差别
*@see1..JDK动态代理对实现了接口的类进行代理
*@see2..CGLIB代理可以对类代理,主要对指定的类生成一个子类。由于是继承,所以目标类最好不要使用final声明
*@see--------------------------------------------------------------------------------------------------
*@see代理方式的选择
*@see1..如果目标对象实现了接口,默认情况下会采用JDK动态代理实现AOP,亦可强制使用CGLIB生成代理实现AOP
*@see2..如果目标对象未实现接口,那么必须引入CGLIB,这时Spring会在JDK动态代理和CGLIB代理之间自动切换
*@see3..比较鼓励业务对象是针对接口编程的,所以鼓励使用JDK动态代理。因为我们所代理的目标,一般都是业务对象
*@see--------------------------------------------------------------------------------------------------
*@see使用CGLIG代理的步骤
*@see1..新增CGLIB库:SPRING_HOME//lib//cglib//*.jar
*@see2..新增配置标签,强制使用CGLIB代理<aop:aspectj-autoproxyproxy-target-class="true"/>
*@see--------------------------------------------------------------------------------------------------
*/
publicclassClient{
publicstaticvoidmain(String[]args){
ApplicationContextfactory=newClassPathXmlApplicationContext("applicationContext-cglib.xml");
//当UserManagerImpl实现了UserManager接口的情况下,这时Spring会自动使用JDK动态代理
//如果项目已经引入cglib库,并在配置文件中强制使用CGLIB代理,此时Spring才会使用CGLIB代理
//UserManageruserManager=(UserManager)factory.getBean("userManager");
//由于此时的UserManagerImpl并没有实现UserManager接口,所以接收类型就不能再使用UserManager接口
//并且项目中已经引入了cglib库,尽管配置文件中没有强制使用CGLIB代理,但Spring会自动使用CGLIB代理
UserManagerImpluserManager=(UserManagerImpl)factory.getBean("userManager");
userManager.addUser("吴三省","02200059");
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。