(一)spring aop的两种配置方式。
sring aop的方式有两种:(1)xml文件配置方式(2)注解的方式实现,我们可以先通过一个demo认识spring aop的实现,然后再对其进行详细的解释。
一、基于注解的springAop配置。
环境准备阶段:
(1)pom.xml:
<dependencies>
<!-- 引入Spring-AOP等相关Jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.3</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.1_2</version>
</dependency> <!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.37</version>
</dependency> <!-- https://mvnrepository.com/artifact/dom4j/dom4j -->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-lang/commons-lang -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
(2)定义接口:
package cn.spring.aop.dao; /**
* @author Simple
* @date 10:01 2019/8/20
* @description
*/
public interface UserService {
public void save();
}
(3)接口实现类:
package cn.spring.aop.dao; import org.springframework.stereotype.Service; /**
* @author Simple
* @date 9:57 2019/8/20
* @description
*/
@Service
public class UserServiceImpl implements UserService { @Override
public void save() {
System.out.println("保存成功.....");
}
}
(4)Aop类:
package cn.spring.aop; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component; /**
* @author Simple
* @date 10:06 2019/8/20
* @description
*/
@Component
@Aspect
public class AopAspect {
/**
* 前置通知
*/
@Before("execution(* cn.spring.aop.dao.UserService.save(..))")
public void before(){
System.out.println("前置通知....");
} /**
* 后置通知
* returnVal,切点方法执行后的返回值
*/
@AfterReturning(value="execution(* cn.spring.aop.dao.UserService.save(..))",returning = "returnVal")
public void AfterReturning(Object returnVal){
System.out.println("后置通知...."+returnVal);
} /**
* 环绕通知
* @param joinPoint 可用于执行切点的类
* @return
* @throws Throwable
*/
@Around("execution(* cn.spring.aop.dao.UserService.save(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕通知前....");
Object obj= (Object) joinPoint.proceed();
System.out.println("环绕通知后....");
return obj;
} /**
* 抛出通知
* @param e
*/
@AfterThrowing(value="execution(* cn.spring.aop.dao.UserService.save(..))",throwing = "e")
public void afterThrowable(Throwable e){
System.out.println("出现异常:msg="+e.getMessage());
} /**
* 无论什么情况下都会执行的方法
*/
@After(value="execution(* cn.spring.aop.dao.UserService.save(..))")
public void after(){
System.out.println("最终通知....");
}
}
(5)spring.xml
<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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解扫描 -->
<context:component-scan base-package="cn.spring.aop"></context:component-scan>
<!-- 启动@aspectj的自动代理支持-->
<aop:aspectj-autoproxy />
</beans>
(6)测试类:
package cn.spring.aop; import cn.spring.aop.dao.UserService;
import cn.spring.aop.dao.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; /**
* @author Simple
* @date 10:13 2019/8/20
* @description
*/
public class TestDemo {
public static void main(String[] args) {
ApplicationContext ac =new ClassPathXmlApplicationContext("spring.xml");
UserService userService = (UserService) ac.getBean("userServiceImpl");
userService.save();
}
}
(7)运行结果:

二、配置详解
(1)spring.xml中注解的作用
1.spring--<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
这个是 开启事物注解权限,引入了三个jar包 aspectjweaver.jar aspectjrt.jar aspectj.jar aopalliance.jar。
2.Spring -- <context:component-scan>
在xml配置了这个标签后,spring可以自动去扫描base-pack下面或者子包下面的java文件,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类注册为bean。
(2)Aop类中的注解
在aop类中,编写了5种注解类型的通知函数:
@Before 前置通知
@AfterReturning 后置通知
@Around 环绕通知
@AfterThrowing 异常通知
@After 最终通知
@pointcut 定义切点匹配表达式
(3)切点表达式
- execution
由于Spring切面粒度最小是达到方法级别,而execution表达式可以用于明确指定方法返回类型,类名,方法名和参数名等与方法相关的部件,并且在Spring中,大部分需要使用AOP的业务场景也只需要达到方法级别即可,因而execution表达式的使用是最为广泛的。如下是execution表达式的语法:
 execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
 这里问号表示当前项可以有也可以没有,其中各项的语义如下:- modifiers-pattern方法的可见性,如public,protected;
- ret-type-pattern:方法的返回值类型,如int,void等;
- declaring-type-pattern:方法所在类的全路径名,如com.spring.Aspect;
- name-pattern:方法名类型,如buisinessService();
- param-pattern:方法的参数类型,如java.lang.String;
- throws-pattern:方法抛出的异常类型,如java.lang.Exception;
如下是一个使用execution表达式的例子:
  execution(public * com.spring.service.BusinessObject.businessService(java.lang.String,..))上述切点表达式将会匹配使用public修饰,返回值为任意类型,并且是com.spring.BusinessObject类中名称为businessService的方法,方法可以有多个参数,但是第一个参数必须是java.lang.String类型的方法。
通配符的类型,主要有两种:
- *通配符,该通配符主要用于匹配单个单词,或者是以某个词为前缀或后缀的单词。
如下示例表示返回值为任意类型,在com.spring.service.BusinessObject类中,并且参数个数为零的方法:execution(* com.spring.service.BusinessObject.*())
- ..通配符,该通配符表示0个或多个项,主要用于declaring-type-pattern和param-pattern中,如果用于declaring-type-pattern中,则表示匹配当前包及其子包,如果用于param-pattern中,则表示匹配0个或多个参数。
如下示例表示匹配返回值为任意类型,并且是com.spring.service包及其子包下的任意类的名称为businessService的方法,而且该方法不能有任何参数:execution(* com.spring.service..*.businessService())
这里需要说明的是,包路径service..*.businessService()中的..应该理解为延续前面的service路径,表示到service路径为止,或者继续延续service路径,从而包括其子包路径;后面的*.businessService(),这里的*表示匹配一个单词,因为是在方法名前,因而表示匹配任意的类。
如下示例是使用..表示任意个数的参数的示例,需要注意,表示参数的时候可以在括号中事先指定某些类型的参数,而其余的参数则由..进行匹配:
execution(* com.spring.service.BusinessObject.businessService(java.lang.String,..))三、基于xml的SpringAop配置
xml配置主要是将注解转换为xml这里我们在上述的情况下做下修改,主要修改两个地方:1,spring.xml,2 aop类
1.springaop.xml
<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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--基于配置需要我们手动进行配置-->
<!-- dao 实例 -->
<bean id="userService" class="cn.spring.aop.dao.UserServiceImpl"></bean>
<!-- 切面类 -->
<bean id="aop" class="cn.spring.aop.AopAspect2"></bean>
<!-- Aop配置 -->
<aop:config>
<!-- 定义一个切入点表达式: 拦截哪些方法 -->
<aop:pointcut expression="execution(* cn.spring.aop.dao.UserService.*(..))" id="pt"/>
<!-- 切面 -->
<aop:aspect ref="aop">
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="pt"/>
<!-- 前置通知: 在目标方法调用前执行 -->
<aop:before method="before" pointcut-ref="pt"/>
<!-- 后置通知: -->
<aop:after method="after" pointcut-ref="pt"/>
<!-- 返回后通知 -->
<aop:after-returning method="afterReturning" pointcut-ref="pt" />
<!-- 异常通知 -->
<aop:after-throwing method="after" pointcut-ref="pt"/>
</aop:aspect>
</aop:config>
</beans>
2.aop类 AopAspect2
package cn.spring.aop; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component; /**
* @author Simple
* @date 10:06 2019/8/20
* @description
*/
@Component
@Aspect
public class AopAspect2 {
/**
* 前置通知
*/
public void before(){
System.out.println("前置通知....");
} /**
* 后置通知
* returnVal,切点方法执行后的返回值
*/
public void afterReturning(){
System.out.println("后置通知....");
} /**
* 环绕通知
* @param joinPoint 可用于执行切点的类
* @return
* @throws Throwable
*/
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕通知前....");
Object obj= (Object) joinPoint.proceed();
System.out.println("环绕通知后....");
return obj;
} /**
* 抛出通知
* @param e
*/
public void afterThrowable(Throwable e){
System.out.println("出现异常:msg="+e.getMessage());
} /**
* 无论什么情况下都会执行的方法
*/
public void after(){
System.out.println("最终通知....");
}
}
3.测试方法
package cn.spring.aop; import cn.spring.aop.dao.UserService;
import cn.spring.aop.dao.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; /**
* @author Simple
* @date 10:13 2019/8/20
* @description
*/
public class TestDemo {
public static void main(String[] args) {
ApplicationContext ac =new ClassPathXmlApplicationContext("springaop.xml");
UserService userService = (UserService) ac.getBean("userService");
userService.save();
}
}
4.运行结果

现在在开发中主要是使用注解进行开发,方便快捷,但是更多的是配置和注解一块使用,springaop在配置方面很多都是这种注解加配置,原因主要是方便管理维护。我们这里主要讲的是两种方式的使用和切点表达式。
(一)spring aop的两种配置方式。的更多相关文章
- spring AOP的两种配置方式
		连接点(JoinPoint) ,就是spring允许你是通知(Advice)的地方,那可就真多了,基本每个方法的前.后(两者都有也行),或抛出异常是时都可以是连接点,spring只支持方法连接点.其他 ... 
- spring ----> aop的两种实现方式
		实现1:基于xml package com.rr.spring3.interf; //接口 public interface SayHello { public void sayHello(); } ... 
- spring AOP的两种配置
		xml配置 定义要被代理的方法的接口 public interface TestAop { public void print(String s); } 实现上述接口 public class Tes ... 
- JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解
		在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ... 
- hibernate  一对一  one to one的两种配置方式
		hibernate中one-to-one两种配置方式 标签: hibernateHibernateone-to-one 2013-02-19 17:44 11445人阅读 评论(1) 收藏 举报 分 ... 
- spring AOP的两种代理
		本篇记录下spring AOP的两种代理,为下一篇AOP实现做下铺垫. 1.JDK动态代理 2.cglib代理 1.如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP2.如果目标对象 ... 
- Hibernate中双向多对多的两种配置方式
		Hibernate中双向多对多的两种配置方式 1.建立多对多双向关联关系 package cn.happy.entitys; import java.util.HashSet; import java ... 
- spring Bean的三种配置方式
		Spring Bean有三种配置方式: 传统的XML配置方式 基于注解的配置 基于类的Java Config 添加spring的maven repository <dependency> ... 
- 学习JavaWeb aop两种配置方式
		aop aop:面向切面编程,它可以解决重复代码. aop有两种方式: 一..xml方式 1.在springmvc-servlet.xml中配置aop,应用bean文件: <!--aop配置-- ... 
随机推荐
- jQuery通过id和name获取值的区别
			$(#'id').函数 $("input[name='name']") 
- 后台post注入爆密码
			后台登陆框post注入按照注入的方式属于post,和前台搜索型post注入.文本框注入类似,由于目前主流的注 入工具除了穿山甲等较新工具以外几乎都是get注入,尤其是对于这种后台账户型post注入式无 ... 
- 基于spring的观察者模式
			简单的说,观察者模式,就类似于 广播站发送广播,和收音机的关系.多个收音机去收听同一个广播频道. 在实际的业务场景中,可以是这样的.创建订单成功后,发布事件.然后减库存.发送短信.调用微信.调用物流服 ... 
- Unity经典游戏教程之:贪吃蛇
			版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ... 
- The introduction of the book American daily English notes (enlarged edition)
			After reading the book of American daily English notes written by Linkun Yang[1], I think I should a ... 
- SpringBoot-Admin的使用
			[**前情提要**]Spring Boot Actuator 提供了对单个 Spring Boot 应用的监控,信息包含应用状态.内存.线程.堆栈等,比较全面的监控了 Spring Boot 应用的整 ... 
- Java 8 Stream实践
			[**前面的话**]Java中的Stream于1.8版本析出,平时项目中也有用到,今天就系统的来实践一下.下面借用重庆力帆队伍中我个人比较喜欢的球员来操作一波,队员的年龄为了便于展示某些api做了调整 ... 
- Java——字符串
			1.不可变的String String对象是不可变的.String类中的每一个看起来会修改String值的方法,实际上都是创建了一个全新的String对象,以包含修改修改后的字符串内容. public ... 
- 守望先锋app(1)
			这个app就是从守望先锋的官网下载相关的图片.文字.视频然后展示出来. 第一个功能是英雄介绍,所以先分析一波官网的数据.守望先锋的英雄数据的官方网站是http://ow.blizzard.cn/her ... 
- struts与springmvc有何区别
			Struts2与SpringMVC有何区别? (1)SpringMVC的核心控制器是基于servlet技术,而Struts2是基于filter. (2)Struts2是类级别的拦截, 一个类对应一个r ... 
