pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yujian</groupId>
<artifactId>spring-aop-demo1</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
</dependencies>
</project>
配置文件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: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">
<!--<bean id="studentService" class="com.yujian.service.StudentService"/>-->
<!--<bean id="logInterceptor" class="com.yujian.log.LogInterceptor"/>
<aop:config>
<aop:aspect id="log" ref="logInterceptor">
其中开始的*代表返回值,紧随的*是包下面的类,然后*为方法名,括号中的是方法输入参数类型或个数
<!–<aop:pointcut id="find" expression="execution(public * *(..))"/>–>
<!–<aop:pointcut id="find" expression="execution(* delete*(..))"/>–>
<aop:pointcut id="find" expression="execution(* com.yujian.service.*.*(..))"/>
<aop:before method="before" pointcut-ref="find"/>
<aop:after method="after" pointcut-ref="find"/>
<aop:after method="before" pointcut-ref="find"/>
<aop:after method="after" pointcut-ref="find"/>
<!–可以插入多个,而且可以通过不写aop:pointcut而是直接写pointcut
前者相当于给pointcut里的execution起个名字多个用–>
<!–<aop:after method="after" pointcut="execution(* com.yujian.service.*.*(..))"/>–>
</aop:aspect>
</aop:config>-->
<context:component-scan base-package="com.yujian"/>
<aop:aspectj-autoproxy/>
</beans>
注解文件
package com.yujian.log;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/*
* (1)Aspect(切面):通常是一个类,里面可以定义切入点和通知
(2)JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用
(3)Advice(通知):AOP在特定的切入点上执行的增强处理,有before,after,afterReturning,afterThrowing,around
(4)Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式
(5)AOP代理:AOP框架创建的对象,代理就是目标对象的加强。Spring中的AOP代理可以使JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于子类
AOP代理给我们假定自动生成一个我们类的子类,连接点(即execution里的位置点,相当于StudnetService里的执行方法,即插入的方法点)
通过连接点的内容,与我们自己建的类糅合一起到子类里,即其实运行的为子类
*/
@Component
@Aspect
public class LogInterceptor {
// 下面其中开始的*代表返回值,紧随的*是包下面的类,然后*为方法名,括号中的是方法输入参数类型或个数
// @Before("execution(* com.yujian.service.*.*(..))")
// @Before("within(com.yujian.service.*)")
/*上面是在service包里的任意连接点(在Spring AOP中只是方法执行) :
* 在service包或者子包里的任意连接点(在Spring AOP中只是方法执行) :
within(com.xyz.service..*)*/
// @Before("this(com.yujian.service.StudentService)")
/*上面这种必须写到类或接口,否则报错
* 实现了 AccountService 接口的代理对象的任意连接点(在Spring AOP中只是方法执行) */
// @Before("target(com.yujian.service.StudentService)")
/*上面这种必须写到类或接口,否则报错
* 实现了 AccountService 接口的目标对象的任意连接点(在Spring AOP中只是方法执行) :*/
@Before("")
public void before(){
System.out.println("执行方法之前");
}
@Pointcut(value = "execution(* com.yujian.service.*.*(..))")
public void log1(){}
/*通过上面这种可以调用空方法,然后想要多个之前之后方法用同一个地方的,即可以
* 用下面的紧接着输出,上面的是一个pointcut标签*/
@After("log1()")
public void after(){
System.out.println("执行方法之后");
}
@Pointcut("execution(* com.yujian.test.*.*(..))")
public void log2(){}
/*下面这种事只有在log2的po之前intcut里满足时才能之前执行*/
@Before("log2()")
public void before1(){
System.out.println("另一个执行方法之前");
}
/*下面这种可以在两个pointcut标签任意一个满足时候,之后执行
* 当然,也可以&&并,两个同时满足,这时候才执行*/
@After("log1()||log2()")
public void after1(){
System.out.println("另一个执行方法之后");
}
}
main函数内
ApplicationContext ctx=new ClassPathXmlApplicationContext("app*.xml");
StudentService studentService=(StudentService) ctx.getBean("studentService");