当spring发现该代理的类实现了接口会使用JDK代理,如果该类没有实现接口,会使用CGLIB代理
如果在springboot中要强制使用CGLIB代理,需要加上
@EnableAspectJAutoProxy(proxyTargetClass = true) // 强制使用 CGLIB
@SpringBootApplication
@EnableAspectJAutoProxy(proxyTargetClass = true) // 强制使用 CGLIB
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
动态代理的典型应用就是AOP
1、动态代理代码示例(JDK)(非AOP)
1.1、定义bean和代理逻辑
// 目标类(实际的业务逻辑)
public class UserService {public void addUser(String username) {System.out.println("User " + username + " added.");}public void deleteUser(String username) {System.out.println("User " + username + " deleted.");}
}// 自定义 InvocationHandler 实现
public class LoggingInvocationHandler implements InvocationHandler {private Object target; // 被代理对象public LoggingInvocationHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 前置逻辑System.out.println("[LOG] Method " + method.getName() + " is called with args: " + java.util.Arrays.toString(args));// 调用目标方法Object result = method.invoke(target, args);// 后置逻辑System.out.println("[LOG] Method " + method.getName() + " execution completed.");return result;}
}
1.2、生成动态代理bean
public class ProxyExample {public static void main(String[] args) {// 创建目标对象(真实的 Bean)UserService userService = new UserService();// 创建代理对象UserService proxy = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(), // 类加载器userService.getClass().getInterfaces(), // 目标类实现的接口new LoggingInvocationHandler(userService) // 代理逻辑);// 调用代理方法proxy.addUser("Alice");proxy.deleteUser("Bob");}
}
结果:
[LOG] Method addUser is called with args: [Alice]
User Alice added.
[LOG] Method addUser execution completed.
[LOG] Method deleteUser is called with args: [Bob]
User Bob deleted.
[LOG] Method deleteUser execution completed.
2、动态代理代码示例(JDK)(AOP)
@Service // 标记为 Spring 容器管理的 Bean
public class UserService {public void addUser(String username) {System.out.println("User " + username + " added.");}public void deleteUser(String username) {System.out.println("User " + username + " deleted.");}
}
@Aspect
@Component // 标记为 Spring 管理的 Bean
public class LoggingAspect {@Before("execution(* com.example.service.UserService.*(..))")public void logBefore(JoinPoint joinPoint) {System.out.println("[LOG] Before method: " + joinPoint.getSignature().getName());}@After("execution(* com.example.service.UserService.*(..))")public void logAfter(JoinPoint joinPoint) {System.out.println("[LOG] After method: " + joinPoint.getSignature().getName());}
}