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

本文演示的是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");
  }
}

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

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索xml
, spring
, aop
aspectj
spring aop aspectj、spring aop和aspectj、aspectj aop.xml、spring aspectj 注解、spring aspectj xml,以便于您获取更多的相关知识。

时间: 2024-11-20 21:04:15

Spring使用AspectJ注解和XML配置实现AOP_java的相关文章

xml和注解混用-spring2.5注解和xml配置混用

问题描述 spring2.5注解和xml配置混用 在使用spring2.5进行开发时,发现一个问题:使用xml配置的bean可以注入到使用Annotation注解的bean里面,**但是使用Annotation注解的bean不能注入到使用xml配置的bean里**面,请问有解决的方法吗? 解决方案 Spring2.5基于注解和XML配置事务管理Spring2.5注解式的配置spring2.5注解 解决方案二: 应该 优先使用注解,XML只做一些数据源或配置文件 等 的.基本上所有的bean都用注

Spring中bean的基本xml配置

xml   在spring容器内拼凑bean叫作装配.装配bean的时候,你是在告诉容器,需要哪些bean,以及容器如何使用依赖注入将它们配合在一起.    理论上,bean装配可以从任何资源获得,包括属性文件,关系数据库等,但xml是最常见的spring 应用系统配置源.Spring中的几种容器都支持使用xml装配bean,包括:    XmlBeanFactory ,    ClassPathXmlApplicationContext ,    FileSystemXmlApplicatio

Spring Aop实例之AspectJ注解配置

       上篇博文<Spring Aop实例之xml配置>中,讲解了xml配置方式,今天来说说AspectJ注解方式去配置spring aop.        依旧采用的jdk代理,接口和实现类代码请参考上篇博文.主要是将Aspect类分享一下: package com.tgb.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lan

详细解说Java Spring的JavaConfig注解

序 传统spring一般都是基于xml配置的,不过后来新增了许多JavaConfig的注解.特别是springboot,基本都是清一色的java config,不了解一下,还真是不适应.这里备注一下. @RestController spring4为了更方便的支持restfull应用的开发,新增了RestController的注解,比Controller注解多的功能就是给底下的RequestMapping方法默认都加上ResponseBody注解,省得自己再去每个去添加该注解. @Configu

基于注解的Spring MVC(所需jar包,web.xml配置,Spring文件配置,@Controller,@RequestMapping,@RequestParam,model填参,EL取值)

1.添加jar 2.web.xml配置: <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5"  xmlns="http://java.sun.com/xml/ns/javaee"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLoca

Spring的注解配置与XML配置之间的比较_java

注释配置相对于 XML 配置具有很多的优势:它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作.如使用 JPA 注释配置 ORM 映射时,我们就不需要指定 PO 的属性名.类型等信息,如果关系表字段和 PO 属性名.类型都一致,您甚至无需编写任务属性映射信息--因为这些信息都可以通过 Java 反射机制获取. 注释和 Java 代码位于一个文件中,而 XML 配置采用独立的配置文件,大多数配置信息在程序开发完成后都不会调整,如果配置信息和 Java 代码放在一起,

Spring 2.5的新特性:配置简化和基于注解的功能

简介 从诞生之初,Spring框架就坚守它的宗旨:简化企业级应用开发,同时给复杂问题提供强大的.非侵入性解决方案.一年前发布的Spring 2.0就把这些主题推到了一个新的高度.XML Schema的支持和自定义命名空间的使用大大减少了基于XML的配置.使用Java 5及更新版本java的开发人员如今可以利用植入了像泛型(generic)和注解等新语言特性的Spring库.最近,和AspectJ表达式语言的紧密集成,使得以非侵入方式添加跨越定义良好的Spring管理对象分组的行为成为可能. 新发

最小化Spring XML配置

spring提供了几种技巧,可以帮助我们减少XML的配置数量: 1.自动装配(autowiring)有助于减少甚至消除配置<property>元素和<constructor-arg>元素,让Spring自动识别如何装配Bean的依赖关系. 2.自动检测(autodiscovery)比自动装配更进了一步,让Spring能够自动识别哪些类需要被配置成Spring Bean,从而减少对<bean>元素的使用.   1.1.自动装配Bean属性 1.1.1.4种类型的自动装配

Spring Aop实例之xml配置

       上篇博文<3幅图让你了解Spring AOP>中介绍了aop通知类型,AOP的配置方式有2种方式:xml配置和AspectJ注解方式.今天我们就来实践一下xml配置方式.       我采用的jdk代理,所以首先将接口和实现类代码附上 package com.tgb.aop; public interface UserManager { public String findUserById(int userId); } package com.tgb.aop; public cl