spring 怎么才会使用代理
-
Spring框架中的代理可以通过两种方式来使用:JDK动态代理和CGLIB动态代理。
-
JDK动态代理:
JDK动态代理是指使用JDK提供的java.lang.reflect.Proxy类来实现代理功能。要使用JDK动态代理,你需要定义一个接口,然后创建一个实现InvocationHandler接口的代理类,实现代理逻辑。最后通过Proxy类的newProxyInstance方法创建代理实例。以下是使用JDK动态代理的示例代码:
public interface UserService { void addUser(); } public class UserServiceImpl implements UserService { public void addUser() { System.out.println("添加用户"); } } public class MyInvocationHandler implements InvocationHandler { private Object target; public MyInvocationHandler(Object target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("方法调用前"); Object result = method.invoke(target, args); System.out.println("方法调用后"); return result; } } public class Main { public static void main(String[] args) { UserService userService = new UserServiceImpl(); MyInvocationHandler handler = new MyInvocationHandler(userService); UserService proxy = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), handler); proxy.addUser(); } }以上代码中,定义了一个UserService接口和其实现类UserServiceImpl。MyInvocationHandler类是自定义的InvocationHandler实现类,其中实现了代理逻辑。在Main类中,创建了一个代理实例proxy,当调用proxy的addUser方法时,实际上会先调用MyInvocationHandler的invoke方法,然后再执行UserServiceImpl的addUser方法。
-
CGLIB动态代理:
CGLIB(Code Generation Library)是一个强大的第三方代码生成库,它可以在运行时动态生成指定类的子类,通过子类来实现代理功能。要使用CGLIB动态代理,你需要引入cglib的相关依赖,然后定义一个类,该类作为被代理的目标对象,再创建一个MethodInterceptor接口的实现类,实现代理逻辑。最后通过Enhancer类的create方法创建代理实例。以下是使用CGLIB动态代理的示例代码:
public class UserService { public void addUser() { System.out.println("添加用户"); } } public class MyInterceptor implements MethodInterceptor { public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("方法调用前"); Object result = proxy.invokeSuper(obj, args); System.out.println("方法调用后"); return result; } } public class Main { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(UserService.class); enhancer.setCallback(new MyInterceptor()); UserService proxy = (UserService) enhancer.create(); proxy.addUser(); } }以上代码中,定义了一个UserService类作为被代理的目标对象。MyInterceptor类是自定义的MethodInterceptor实现类,其中实现了代理逻辑。在Main类中,创建了一个代理实例proxy,当调用proxy的addUser方法时,实际上会先调用MyInterceptor的intercept方法,然后再执行UserService的addUser方法。
以上就是Spring框架中使用代理的两种方式。可以根据具体的需求选择合适的方式来实现代理功能。
1年前 -
-
Spring框架是一个非常流行的开源框架,主要用于创建企业级Java应用程序。Spring中的代理是一种常见的设计模式,可以通过代理实现额外的功能。
以下是在Spring中使用代理的几种常见方式:
- JDK动态代理:JDK动态代理是通过实现
java.lang.reflect.InvocationHandler接口来实现的。使用JDK动态代理时,目标对象必须实现至少一个接口。通过调用Proxy.newProxyInstance()方法来创建代理对象,并将目标对象的方法调用转发到代理对象。
举例来说,假设我们有一个接口
UserService和它的实现类UserServiceImpl。我们可以创建一个实现了InvocationHandler接口的代理类,将目标对象的方法调用转发到代理对象。public class UserServiceProxy implements InvocationHandler { private UserService userService; // 目标对象 public UserServiceProxy(UserService userService) { this.userService = userService; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 在目标方法调用前做一些额外的处理 System.out.println("Before method execution"); // 调用目标对象的方法 Object result = method.invoke(userService, args); // 在目标方法调用后做一些额外的处理 System.out.println("After method execution"); return result; } } // 创建代理对象 UserService userServiceProxy = (UserService) Proxy.newProxyInstance( UserService.class.getClassLoader(), new Class[] {UserService.class}, new UserServiceProxy(new UserServiceImpl()) ); // 使用代理对象调用方法 userServiceProxy.getUser(123);- CGLib动态代理:CGLib动态代理可以用于代理没有实现接口的类。CGLib通过继承目标对象来实现代理。在运行时,CGLib会创建目标对象的子类,并重写目标对象中的方法。通过调用
Enhancer.create()方法来创建代理对象。
举例来说,假设我们有一个类
UserService,我们可以使用CGLib动态代理来创建它的代理对象。public class UserService { public void getUser(int userId) { // ... } } public class UserServiceInterceptor implements MethodInterceptor { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { // 在目标方法调用前做一些额外的处理 System.out.println("Before method execution"); // 调用目标方法 Object result = proxy.invokeSuper(obj, args); // 在目标方法调用后做一些额外的处理 System.out.println("After method execution"); return result; } } // 创建代理对象 Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(UserService.class); enhancer.setCallback(new UserServiceInterceptor()); UserService userServiceProxy = (UserService) enhancer.create(); // 使用代理对象调用方法 userServiceProxy.getUser(123);- 基于注解的代理:Spring还提供了基于注解的代理功能,使代理配置更加便捷。通过在目标类上添加
@Transactional等注解,可以将添加事务的逻辑应用到目标方法上。Spring会通过自动代理机制,在运行时动态地为带有注解的类创建代理对象。
示例代码如下:
@Service public class UserService { @Transactional public void addUser(User user) { // ... } } // 在配置文件中启用基于注解的代理 <tx:annotation-driven /> // 创建代理对象 @Autowired private UserService userService; // 使用代理对象调用方法 userService.addUser(user);- 静态代理:除了动态代理外,Spring还支持静态代理。静态代理是指在开发阶段就已经创建并编译好的代理类。静态代理需要为每个需要代理的类编写一个代理类,通过调用代理类的方法来间接调用目标对象的方法。
示例代码如下:
public interface UserService { void getUser(int userId); } public class UserServiceImpl implements UserService { @Override public void getUser(int userId) { // ... } } public class UserServiceProxy implements UserService { private UserService userService; public UserServiceProxy(UserService userService) { this.userService = userService; } @Override public void getUser(int userId) { // 在目标方法调用前做一些额外的处理 System.out.println("Before method execution"); // 调用目标对象的方法 userService.getUser(userId); // 在目标方法调用后做一些额外的处理 System.out.println("After method execution"); } } // 创建代理对象 UserService userService = new UserServiceImpl(); UserService userServiceProxy = new UserServiceProxy(userService); // 使用代理对象调用方法 userServiceProxy.getUser(123);- Spring AOP:Spring AOP(面向切面编程)是一种使用代理的方式来实现横切关注点的重用。通过定义切点(连接点的集合),然后为这些切点定义通知(在特定连接点执行的代码)来实现。Spring AOP可以使用动态代理(默认使用JDK动态代理)或CGLib代理来创建代理对象。
示例代码如下:
@Aspect @Component public class LogAspect { @Before("execution(* com.example.UserService.getUser(..))") public void logBefore(JoinPoint joinPoint) { System.out.println("Before method execution"); } @After("execution(* com.example.UserService.getUser(..))") public void logAfter(JoinPoint joinPoint) { System.out.println("After method execution"); } } @Configuration @EnableAspectJAutoProxy public class AppConfig { // 配置AOP }上述是在Spring中使用代理的几种常见方式。根据具体的需求和场景,选择合适的代理方式可以提供更好的代码重用性、可维护性和可测试性。
1年前 - JDK动态代理:JDK动态代理是通过实现
-
要使用代理,可以使用Spring框架提供的两种代理方式:JDK动态代理和CGLIB代理。下面将详细介绍每种代理方式的使用方法和操作流程。
- JDK动态代理:
JDK动态代理是通过反射机制实现的,要使用JDK动态代理,首先需要定义一个接口,然后创建一个实现该接口的代理类。代理类需要实现InvocationHandler接口,并重写invoke方法,该方法会在调用代理对象的方法时触发。
(1)定义接口:
public interface UserService { public void addUser(String username, String password); public void deleteUser(int userId); }(2)创建实现接口的目标对象:
public class UserServiceImpl implements UserService { @Override public void addUser(String username, String password) { System.out.println("User added: " + username); } @Override public void deleteUser(int userId) { System.out.println("User deleted, ID: " + userId); } }(3)创建代理类:
public class UserServiceProxy implements InvocationHandler { private Object target; public Object bind(Object target) { this.target = target; return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Before method: " + method.getName()); // 在方法之前执行的逻辑 Object result = method.invoke(target, args); // 调用目标对象的方法 System.out.println("After method: " + method.getName()); // 在方法之后执行的逻辑 return result; } }(4)使用代理对象:
public class Main { public static void main(String[] args) { UserService target = new UserServiceImpl(); UserService proxy = (UserService) new UserServiceProxy().bind(target); proxy.addUser("Alice", "123456"); proxy.deleteUser(1); } }- CGLIB代理:
CGLIB代理是通过继承目标类来生成代理对象的。要使用CGLIB代理,首先需要引入cglib的依赖,然后创建一个代理类,并通过Enhancer类设置目标类和回调对象。
(1)引入cglib的依赖:
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> </dependency>(2)创建实现类:
public class UserService { public void addUser(String username, String password) { System.out.println("User added: " + username); } public void deleteUser(int userId) { System.out.println("User deleted, ID: " + userId); } }(3)创建代理类:
public class UserServiceProxy implements MethodInterceptor { private Object target; public Object getInstance(Object target) { this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.target.getClass()); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("Before method: " + method.getName()); // 在方法之前执行的逻辑 Object result = method.invoke(target, args); // 调用目标对象的方法 System.out.println("After method: " + method.getName()); // 在方法之后执行的逻辑 return result; } }(4)使用代理对象:
public class Main { public static void main(String[] args) { UserService target = new UserService(); UserService proxy = (UserService) new UserServiceProxy().getInstance(target); proxy.addUser("Alice", "123456"); proxy.deleteUser(1); } }以上就是使用Spring框架实现代理的方法和操作流程。通过JDK动态代理和CGLIB代理,可以在目标类的方法执行前后增加自定义的逻辑。这在实际开发中经常用于事务管理、日志记录、性能监控等功能的实现。
1年前 - JDK动态代理: