欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring使用AspectJ注解和XML配置实现AOP

程序员文章站 2024-03-12 09:25:38
本文演示的是spring中使用aspectj注解和xml配置两种方式实现aop 下面是使用aspectj注解实现aop的java project 首先是位于clas...

本文演示的是spring中使用aspectj注解和xml配置两种方式实现aop

下面是使用aspectj注解实现aop的java project
首先是位于classpath下的applicationcontext.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" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    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/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> 
   
  <!-- 启用aspectj对annotation的支持 -->     
  <aop:aspectj-autoproxy/> 
       
  <bean id="usermanager" class="com.jadyer.annotation.usermanagerimpl"/> 
   
  <bean id="securityhandler" class="com.jadyer.annotation.securityhandler"/> 
</beans> 

然后是服务层接口以及实现类

package com.jadyer.annotation; 
public interface usermanager { 
  public void adduser(string username, string password); 
  public void deluser(int userid); 
  public string finduserbyid(int userid); 
  public void modifyuser(int userid, string username, string password); 
} 
 
/** 
 * 上面的usermanager是服务层的接口 
 * 下面的usermanagerimpl是服务层接口的实现类 
 */ 
 
package com.jadyer.annotation; 
 
public class usermanagerimpl implements usermanager { 
  public void adduser(string username, string password) { 
    system.out.println("------usermanagerimpl.adduser() is invoked------"); 
  } 
 
  public void deluser(int userid) { 
    system.out.println("------usermanagerimpl.deluser() is invoked------"); 
  } 
 
  public string finduserbyid(int userid) { 
    system.out.println("------usermanagerimpl.finduserbyid() is invoked------"); 
    return "铁面生"; 
  } 
 
  public void modifyuser(int userid, string username, string password) { 
    system.out.println("------usermanagerimpl.modifyuser() is invoked------"); 
  } 
} 

接下来是使用aspectj注解标注的切入类

package com.jadyer.annotation; 
 
import org.aspectj.lang.annotation.after; 
import org.aspectj.lang.annotation.aspect; 
import org.aspectj.lang.annotation.pointcut; 
 
@aspect 
public class securityhandler { 
  /** 
   * 定义pointcut 
   * @see pointcut的名称为addaddmethod(),此方法没有返回值和参数 
   * @see 该方法就是一个标识,不进行调用 
   */ 
  @pointcut("execution(* add*(..))") //匹配所有以add开头的方法 
  private void addaddmethod(){}; 
   
  /** 
   * 定义advice 
   * @see 表示我们的advice应用到哪些pointcut订阅的joinpoint上 
   */ 
  //@before("addaddmethod()") 
  @after("addaddmethod()") 
  private void checksecurity() { 
    system.out.println("------【checksecurity is invoked】------"); 
  }     
} 

最后是客户端测试类

package com.jadyer.annotation; 
 
import org.springframework.context.applicationcontext; 
import org.springframework.context.support.classpathxmlapplicationcontext; 
 
/** 
 * spring对aop的支持:采用annotation方式 
 * @see ------------------------------------------------------------------------------------- 
 * @see spring提供的aop功能还是很强大的,支持可配置,它的默认实现使用的就是jdk动态代理 
 * @see 使用spring的aop不需要继承相关的东西,也不需要实现接口 
 * @see 但有个前提条件:由于是jdk动态代理,所以若想生成代理,该类就必须得实现一个接口才行 
 * @see 如果该类没有implements接口的话,仍去使用spring的默认aop实现时,那么就会出错 
 * @see 通常需要生成代理的类都是服务层的类,所以通常都会抽一个接口出来。即养成面向接口编程的习惯 
 * @see ------------------------------------------------------------------------------------- 
 * @see 采用annotation方式完成aop示例的基本步骤,如下 
 * @see 1、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 
 * @see 2、将横切性关注点模块化,建立securityhandler.java 
 * @see 3、采用注解指定securityhandler为aspect 
 * @see 4、采用注解定义advice和pointcut 
 * @see 5、启用aspectj对annotation的支持,并且将目标类和aspect类配置到ioc容器中 
 * @see 6、开发客户端 
 * @see ------------------------------------------------------------------------------------- 
 */ 
public class client { 
  public static void main(string[] args) { 
    applicationcontext factory = new classpathxmlapplicationcontext("applicationcontext.xml"); 
    usermanager usermanager = (usermanager)factory.getbean("usermanager"); 
    usermanager.adduser("张起灵", "02200059"); 
  } 
} 

下面是使用xml配置文件实现aop的java project
首先是位于src根目录中的applicationcontext-cglib.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" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    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/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> 
       
  <!-- 强制使用cglib代理 --> 
  <!-- <aop:aspectj-autoproxy proxy-target-class="true"/> --> 
   
  <bean id="usermanager" class="com.jadyer.cglib.usermanagerimpl"/> 
   
  <bean id="securityhandler" class="com.jadyer.cglib.securityhandler"/> 
   
  <aop:config> 
    <aop:aspect id="securityaspect" ref="securityhandler">  
      <aop:pointcut id="addaddmethod" expression="execution(* add*(..))"/> 
      <aop:before method="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*(..)) 
 --> 

然后是服务层接口以及实现类

package com.jadyer.cglib; 
public interface usermanager { 
  public void adduser(string username, string password); 
  public void deluser(int userid); 
  public string finduserbyid(int userid); 
  public void modifyuser(int userid, string username, string password); 
} 
 
/** 
 * 上面的usermanager是服务层接口 
 * 下面的usermanagerimpl是服务层接口的实现类 
 */ 
 
package com.jadyer.cglib; 
 
public class usermanagerimpl {  
//implements usermanager { 
  public void adduser(string username, string password) { 
    system.out.println("------usermanagerimpl.adduser() is invoked------"); 
  } 
 
  public void deluser(int userid) { 
    system.out.println("------usermanagerimpl.deluser() is invoked------"); 
  } 
 
  public string finduserbyid(int userid) { 
    system.out.println("------usermanagerimpl.finduserbyid() is invoked------"); 
    return "张三"; 
  } 
 
  public void modifyuser(int userid, string username, string password) { 
    system.out.println("------usermanagerimpl.modifyuser() is invoked------"); 
  } 
} 

接着是在applicationcontext-cglib.xml中所指定的切入类

package com.jadyer.cglib; 
 
import org.aspectj.lang.joinpoint; 
 
/** 
 * 将客户调用信息传递到该advice中 
 * @see 可以在advice中添加一个joinpoint参数,取得客户端调用的方法名称及参数值 
 * @see 以后纯粹使用aop去写类似这样东西的情况比较少,我们主要使用spring提供的事务 
 * @see 关于这个,知道即可。下面是示例代码 
 */ 
public class securityhandler { 
  private void checksecurity(joinpoint joinpoint) { 
    for (int i=0; i<joinpoint.getargs().length; i++) { 
      system.out.println(joinpoint.getargs()[i]); //获取客户端调用的方法的参数值 
    } 
    system.out.println(joinpoint.getsignature().getname()); //获取客户端调用的方法名称 
    system.out.println("------【checksecurity is invoked】------"); 
  } 
} 

最后是客户端测试类

package com.jadyer.cglib; 
 
import org.springframework.context.applicationcontext; 
import org.springframework.context.support.classpathxmlapplicationcontext; 
 
/** 
 * @see -------------------------------------------------------------------------------------------------- 
 * @see jdk动态代理和cglib代理的差别 
 * @see 1..jdk动态代理对实现了接口的类进行代理 
 * @see 2..cglib代理可以对类代理,主要对指定的类生成一个子类。由于是继承,所以目标类最好不要使用final声明 
 * @see -------------------------------------------------------------------------------------------------- 
 * @see 代理方式的选择 
 * @see 1..如果目标对象实现了接口,默认情况下会采用jdk动态代理实现aop,亦可强制使用cglib生成代理实现aop 
 * @see 2..如果目标对象未实现接口,那么必须引入cglib,这时spring会在jdk动态代理和cglib代理之间自动切换 
 * @see 3..比较鼓励业务对象是针对接口编程的,所以鼓励使用jdk动态代理。因为我们所代理的目标,一般都是业务对象 
 * @see -------------------------------------------------------------------------------------------------- 
 * @see 使用cglig代理的步骤 
 * @see 1..新增cglib库:spring_home//lib//cglib//*.jar 
 * @see 2..新增配置标签,强制使用cglib代理<aop:aspectj-autoproxy proxy-target-class="true"/> 
 * @see -------------------------------------------------------------------------------------------------- 
 */ 
public class client { 
  public static void main(string[] args) { 
    applicationcontext factory = new classpathxmlapplicationcontext("applicationcontext-cglib.xml"); 
     
    //当usermanagerimpl实现了usermanager接口的情况下,这时spring会自动使用jdk动态代理 
    //如果项目已经引入cglib库,并在配置文件中强制使用cglib代理,此时spring才会使用cglib代理 
    //usermanager usermanager = (usermanager)factory.getbean("usermanager"); 
     
    //由于此时的usermanagerimpl并没有实现usermanager接口,所以接收类型就不能再使用usermanager接口 
    //并且项目中已经引入了cglib库,尽管配置文件中没有强制使用cglib代理,但spring会自动使用cglib代理    
    usermanagerimpl usermanager = (usermanagerimpl)factory.getbean("usermanager"); 
     
    usermanager.adduser("吴三省", "02200059"); 
  } 
} 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。