Spring使用AspectJ注解和XML配置实现AOP
作者:玄玉 发布时间:2023-02-01 09:45:03
标签:Spring,AspectJ,XML,AOP
本文演示的是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");
}
}


猜你喜欢
- private string HttpPost(string Url, string postDataStr)
- 上一篇实现了移动端微信消息界面功能,以此为基础继续完善服务端功能服务端微信消息页实现微信消息界面的实现,和登录,注册是类似的,无非就是接受客
- SpringCloud @FeignClient 参数详解今天因为工作中遇到FeignClient一个奇葩的bug,后面仔细研究了,找出了原
- 阅读收获理解SpringBoot自动配置原理一、SpringBoot是什么SpringBoot 的诞生就是为了简化 Spring 中繁琐的
- 准备工作:import java.text.SimpleDateFormat;import java.util.Calendar;impor
- Spring Boot 默认为我们提供了静态资源处理,使用 WebMvcAutoConfiguration 中的配置各种属性。建议大家使用S
- springboot部署项目在linux的两种方式 可以选择 war包方式或者jar包方式(个人推荐使用jar方式)1.springboot
- 使用ehcache-spring-annotations使得在工程中简单配置即可使用缓存下载地址:http://code.google.co
- 前言先放一个官网吧,其实本案例就是根据官网案例来的,只是进行了修改配置。Mybatis-plus官网一、搭建一个springboot项目&n
- 一、项目前提1、购物车并不是一直放数据库2、选择使用的技术:session:(购物车项目使用session)好处:快(放在内存当中),存对象
- 重点重点重点,不然会报错连接数据库url后面加个参数allowMultiQueries=true用习惯了 insertList 怎么能没有
- 一、引言想实现一个空白的画板,上面可以画出手滑动的轨迹,就这么一个小需求。一般就来讲就两种实现方式,view或者surfaceview。下面
- 一、项目简述功能: 系统分为三个角色。最高权限管理员,学生,教师,包括 学生管理,教师管理,课程管理,选课,退课,成绩查 询。,教学课程,查
- 本文实例讲述了Java递归基础与递归的宏观语意。分享给大家供大家参考,具体如下:1.什么是递归本质上,将原来的问题,转化为更小的同一问题2.
- ImageCacheconst int _kDefaultSize = 1000;const int _kDefaultSizeBytes
- java就业前需要掌握的专业技能1.熟练的使用Java语言进行面向对象程序设计,有良好的编程习惯,熟悉常用的Java API,包括集合框架、
- 一、using语句using可以算是.NET中新的语法元素,它清楚地说明一个通常比较占用资源的对象何时开始使用和何时被手动释放。当using
- 1. 对象的创建对象创建的主要流程:1.类加载检查虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引
- 现在我们上网会用百度或者谷歌搜索信息,当我们在输入框里输入一两个字后,就会自动提示我们想要的信息,这种效果在Android 是通过
- 下面通过代码看下springboot 跨域配置类,代码如下所示:ackage org.fh.config;import java.io.IO