一、概述
1、如果目标对象实现了接口,在默认情况下会采用JDK的动态代理实现;
2、如果目标对象实现了接口,也可以强制使用CGLIB生成代理实现AOP;
3、如果目标对象没有实现接口,那么必须引入CGLIB,Spring会在JDK的动态代理和CGLIB之间切换。
二、如何强制使用CGLIB
1、加入CGLIB库,cglib-nodep-3.2.0.jar
2、加入如下配置,强制使用CGLIB代理
<!-- 强制使用CGLIB代理 -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
三、JDK动态代理和CGLIB代理的区别
1、JDK动态代理对实现了接口的类进行代理
2、CGLIB代理可以对类代理,主要对指定的类生成一个类,因为是继承,目标类最好不要使用final进行声明
四、代码描述
1、UserManagerImpl.java
package com.lty.aop.spring.cglib;
public class UserManagerImpl {
//implements UserManager {
// @Override
public void addUser(String username, String password) {
System.out.println("----------UserManagerImpl.addUser()---------");
}
// @Override
public void delUser(int userId) {
System.out.println("----------UserManagerImpl.delUser()---------");
}
// @Override
public String findUserById(int userId) {
System.out.println("----------UserManagerImpl.findUserById()---------");
return "张三";
}
// @Override
public void modifyUser(int userId, String username, String password) {
System.out.println("----------UserManagerImpl.modifyUser()---------");
}
}
2、SecurityHandler.java
package com.lty.aop.spring.cglib;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
public class SecurityHandler{
public void checkSecurity(JoinPoint joinPoint){
System.out.println("-----------checkSecurity()---------");
String methodName = joinPoint.getSignature().getName();
System.out.println("methodName: " + methodName + " arguments: " + Arrays.asList(joinPoint.getArgs()));
}
public void recordLogging(){
System.out.println("-----------recordLogging()---------");
}
}
3、Client.java
package com.lty.aop.spring.cglib;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Client {
public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("applicationContext-xml-cglib.xml");
// UserManager userManager = (UserManager) beanFactory.getBean("userManager");
UserManagerImpl userManager = (UserManagerImpl) beanFactory.getBean("userManager");
userManager.addUser("张三", "123");
System.out.println(userManager.findUserById(1));
userManager.delUser(1);
}
}
4、applicationContext-xml-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"
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-4.0.xsd">
<!-- 强制使用CGLIB代理 -->
<!-- <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy> -->
<!-- 将实现类注入IOC容器中 -->
<bean id="userManager" class="com.lty.aop.spring.cglib.UserManagerImpl"></bean>
<!-- 将切面类也注入IOC容器中 -->
<bean id="securityHandler" class="com.lty.aop.spring.cglib.SecurityHandler"></bean>
<!-- Spring AOP xml配置 -->
<aop:config>
<!-- <aop:pointcut expression="execution(* add*(..))" id="securityPointcut"/> -->
<!-- <aop:pointcut expression="execution(* com.lty.aop.spring.xml.UserManagerImpl.*(..))" id="securityPointcut"/> -->
<aop:pointcut expression="execution(* com.lty.aop.spring.cglib.UserManagerImpl.add*(..)) || execution(* com.lty.aop.spring.cglib.UserManagerImpl.del*(..))" id="securityPointcut"/>
<aop:aspect ref="securityHandler">
<aop:before method="checkSecurity" pointcut-ref="securityPointcut"/>
<aop:after method="recordLogging" pointcut-ref="securityPointcut"/>
</aop:aspect>
</aop:config>
</beans>