一、使用配置文件
引入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<!--aop-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.2</version>
</dependency>
// 被代理的类
public class Tank {
public void move(){
System.out.println("tank移动。。。。");
}
}
// 代理类
public class LogProxy {
public void before(){
System.out.println("before");
}
public void after(){
System.out.println("after");
}
}
测试类
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) throws Exception{
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("app.xml");
Tank tank = context.getBean("tank", Tank.class);
tank.move();
}
}
配置文件
<?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 id="tank" class="com.zxh.proxy.v12spingaop.v1.Tank"></bean>
<bean id="timeProxy" class="com.zxh.proxy.v12spingaop.v1.LogProxy"></bean>
<aop:config>
<aop:aspect id="log" ref="timeProxy">
<aop:pointcut id="onmove" expression="execution(void com.zxh.proxy.v12spingaop.v1.Tank.move())"/>
<aop:after method="after" pointcut-ref="onmove"/>
<aop:before method="before" pointcut-ref="onmove"/>
</aop:aspect>
</aop:config>
</beans>
二、使用注解
同样是引入上面的依赖
然后在配置文件中开启注解
<?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 id="tank" class="com.zxh.proxy.v12spingaop.v2.Tank"></bean>
<bean id="timeProxy" class="com.zxh.proxy.v12spingaop.v2.LogProxy"></bean>
<!--开启aop注解-->
<aop:aspectj-autoproxy/>
</beans>
import org.springframework.stereotype.Component;
public class Tank {
public void move(){
System.out.println("tank移动。。。。");
}
}
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class LogProxy {
@Before("execution(void com.zxh.proxy.v12spingaop.v2.Tank.move())")
public void before(){
System.out.println("before");
}
@After("execution(void com.zxh.proxy.v12spingaop.v2.Tank.move())")
public void after(){
System.out.println("after");
}
}
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("app_auto.xml");
Tank tank = context.getBean("tank",Tank.class);
tank.move();
}
}
原理讲解
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("app_auto.xml");
Object o = context.getBean("tank");
String name = o.getClass().getName();
String superName = o.getClass().getSuperclass().getName();
System.out.println("类名:"+name);
System.out.println("父类类名:"+superName);
}
}
输出结果
类名:com.zxh.proxy.v12spingaop.v2.Tank$$EnhancerBySpringCGLIB$$af10011d
父类类名:com.zxh.proxy.v12spingaop.v2.Tank
由此可知SpringAOP
采用的是cglib
的方式动态生成了代理。
cglib是使用继承的方法生成的代理。
我们通过IOC容器获取到Tank对象实际上是Tank对象的子类,而这个子类就是就是Tank的代理类