一、前置学习与准备:
1、AOP原理:springAOP原理–java动态代理之java.lang.reflect.Proxy.newProxyInstance
2、AOP术语:https://blog.csdn.net/changudeng1992/article/details/80625134
3、切入点表达式:https://blog.csdn.net/qq_39720594/article/details/105321664
4、引入依赖:
aopalliance-1.0.jar
aspectjweaver-1.6.8.jar
cglib-2.2.jar
commons-logging-1.1.1.jar
spring-aop-5.2.6.RELEASE.jar
spring-aspects-5.2.6.RELEASE.jar
spring-beans-5.2.6.RELEASE.jar
spring-context-5.2.6.RELEASE.jar
spring-core-5.2.6.RELEASE.jar
spring-expression-5.2.6.RELEASE.jar
二、注解方式实现aop
xml:aop.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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="com.my.aop"/>
<!--开启Aspect生成代理对象-->
<aop:aspectj-autoproxy />
</beans>
底层接口:UserDao.java
package com.my.aop;
public interface UserDao {
void plus(int a, int b);
String show(String str);
}
实现类:UserDaoImpl.java
package com.my.aop;
import org.springframework.stereotype.Component;
@Component
public class UserDaoImpl implements UserDao {
@Override
public void plus(int a, int b) {
System.out.println("plus...");
}
@Override
public String show(String str) {
System.out.println("show...");
return "show..." + str;
}
}
代理类:UserDaoImplProxy.java
package com.my.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Aspect // 生成代理对象
@Order(3) // 代理优先级,数字越小越优先
class UserDaoImplProxy {
// 前置通知
@Before(value = "execution(* com.my.aop.UserDaoImpl.*(..))")
public void before(){
System.out.println("before..");
}
//方法结束之后执行,最终通知
@After(value = "execution(* com.my.aop.UserDaoImpl.*(..))")
public void after(){
System.out.println("after..");
}
// 异常通知
@AfterThrowing(value = "execution(* com.my.aop.UserDaoImpl.*(..))")
public void afterThrowing(){
System.out.println("afterThrowing...");
}
//方法返回值之后执行,返回通知
@AfterReturning(value = "execution(* com.my.aop.UserDaoImpl.*(..))")
public void afterReturning(){
System.out.println("afterReturning...");
}
// 环绕通知,方法前后都会执行
@Around(value = "execution(* com.my.aop.UserDaoImpl.*(..))")
public void around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("around before...");
pjp.proceed();
System.out.println("around after...");
}
}
代理类:UserDaoImplProxy1.java(公共切入点与代理优先级)
package com.my.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Aspect // 生成代理对象
@Order(1)// 代理优先级,数字越小越优先
class UserDaoImplProxy1 {
// 公共切入点
@Pointcut(value = "execution(* com.my.aop.UserDaoImpl.*(..))")
public void commonPointCut(){
}
// 前置通知
@Before(value = "commonPointCut()") // 使用公共切入点
public void before(){
System.out.println("before..1");
}
//方法结束之后执行,最终通知
@After(value = "commonPointCut()")
public void after(){
System.out.println("after..1");
}
// 异常通知
@AfterThrowing(value = "commonPointCut()")
public void afterThrowing(){
System.out.println("afterThrowing...1");
}
//方法返回值之后执行,返回通知
@AfterReturning(value = "commonPointCut()")
public void afterReturning(){
System.out.println("afterReturning...1");
}
// 环绕通知,方法前后都会执行
@Around(value = "commonPointCut()")
public void around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("around before...1");
pjp.proceed();
System.out.println("around after...1");
}
}
测试类:
package com.my.aop;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
class AopTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("aop.xml");
UserDao userDaoImpl = context.getBean("userDaoImpl",UserDao.class);
userDaoImpl.plus(3,4);
System.out.println("======================");
userDaoImpl.show("3,4");
}
}
输出:
around before…1
before…1
around before…
before…
plus…
around after…
after…
afterReturning…
around after…1
after…1
afterReturning…1
around before…1
before…1
around before…
before…
show…
around after…
after…
afterReturning…
around after…1
after…1
afterReturning…1
三、配置文件方式实现aop
定义类:User.java
package com.my.aopxml;
public class User {
public void plus(int a, int b) {
System.out.println("plus...");
}
public String show(String str) {
System.out.println("show...");
return "show..." + str;
}
}
增强类:UserProxy.java
package com.my.aopxml;
public class UserProxy {
public void before(){
System.out.println("before......");
}
}
xml:aopxml.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--定义类与增强类的bean-->
<bean id="user" class="com.my.aopxml.User"/>
<bean id="userProxy" class="com.my.aopxml.UserProxy"/>
<!--aop的配置-->
<aop:config>
<!--切入点配置-->
<aop:pointcut id="pc" expression="execution(* com.my.aopxml.User.*(..))"/>
<!--aspect定义-->
<aop:aspect ref="userProxy">
<!--前置通知 使用方式before 使用id为pc的切入点-->
<aop:before method="before" pointcut-ref="pc"/>
</aop:aspect>
</aop:config>
</beans>
测试类:UserTest.java
package com.my.aopxml;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("aopxml.xml");
User user = context.getBean("user", User.class);
user.show("usershow");
}
}
输出:
before…
show…
四、完全注解开发
定义类:User.java,添加注解@Component
package com.my.aopxml;
import org.springframework.stereotype.Component;
@Component
public class User {
public void show(String str) {
System.out.println("User show...");
}
}
增强类:UserProxy.java,添加注解@Component,@Aspect,方法注解@Before
package com.my.aopxml;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class UserProxy {
@Before(value = "execution(* com.my.aopxml.User.*(..))")
public void before(){
System.out.println("before......");
}
}
配置类:AopConfig.xml,@Configuration,@ComponentScan,@EnableAspectJAutoProxy
package com.my.aopxml;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@ComponentScan(basePackages = {"com.my.aopxml"})
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AopConfig {
}
测试类:
package com.my.aopxml;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class UserTest {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class);
User user = context.getBean("user", User.class);
user.show("ddd");
}
}
输出:
before…
User show…