Java implements a simple interceptor operation through dynamic proxies
- 2021-10-25 06:45:36
- OfStack
1. Agents
Before using dynamic proxies to implement interceptors, let's have a brief look at what Java proxies are.
Proxy, as its name implies, does not directly manipulate the proxy object (hereinafter referred to as the target object, which sounds comfortable), but indirectly uses the methods in the target object through a proxy object. Proxy is divided into two modes, one is static proxy and the other is dynamic proxy. Next, write an example of a static proxy.
Whether it is a static proxy or a dynamic proxy, the target object (target) must implement an interface (interface). Note that if you use the proxy provided by cglib, you don't have to implement the interface, but implement it through subclasses, so this method will not be discussed for the time being.
(1) Define an interface first
public interface IUserDao {
void save();
}
(2) Define the target object (target)
public class UserDaoImpl implements IUserDao {
public void save() {
System.out.println("-------- Data has been saved ---------");
}
}
(3) Define proxy objects
public class UserDaoProxy implements IUserDao {
private IUserDao target;// Place the target object in the proxy object
public UserDaoProxy(IUserDao target){
this.target = target;
}
public void save() {
System.out.println("------ Start a transaction ------");
target.save();
System.out.println("------- Commit transaction ------");
}
}
Under Test 1:
public class Test {
public static void main(String[] args){
IUserDao userDao = new UserDaoImpl();
UserDaoProxy proxy = new UserDaoProxy(userDao);
proxy.save();// Called through a proxy object save Method
}
}
The output is:
--Start business--
--------------Submission of business--
One problem with this approach is that the proxy object must also implement the same interface implemented by the proxy object, which leads to serious coupling. Therefore, one improved method is used below, that is, dynamic proxy (jdk proxy).
Dynamic proxy also requires the target object (target) to implement an interface
(1) Define an interface (IUserDao)
(2) Define a target object class (UserDaoImpl)
(3) Create a dynamic proxy class
public class ProxyFactory {
// Maintenance 1 Target objects
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
// Generate a proxy object for the target object
public Object getProxyInstance() {
System.out.println("----target class---" + target.getClass());
System.out.println("----target interfaces---" +
target.getClass().getInterfaces());
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("---- Start a transaction 2-----");
// Execute the target object method
Object returnValue = method.invoke(target, args);
System.out.println("---- Commit transaction 2----");
return returnValue;
}
});
}
}
Under Test 1:
public class Test {
public static void main(String[] args) {
// Target object
IUserDao target = new UserDao();
System.out.println(target.getClass());
// Create a proxy object for the target object
IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
System.out.println("----proxy---- : " + proxy.getClass());
proxy.save();
proxy.delete();
}
}
Output:
class com.jd.pattern.proxy.dynamicProxy.UserDao
----target class---class com.jd.pattern.proxy.dynamicProxy.UserDao
----target interfaces---[Ljava.lang.Class;@1fb3ebeb
--proxy--: class com. sun. proxy. $Proxy0
--Start business 2---
--Save complete---
Commit transaction 2--
--Start business 2---
--Deletion complete--Commit transaction 2--
2. Implement a simple interceptor using a dynamic proxy
Since the dynamic proxy is used, there must be an interface, a target class, a proxy class, and an interceptor
1. Define an interface
public interface BusinessFacade {
void doSomething();
}
2. Define a target object
public class BusinessClass implements BusinessFacade {
public void doSomething() {
System.out.println(" In the business component BusinessClass Call in doSomething Method ");
}
}
3. Create an interceptor
public class InterceptorClass {
public void before() {
System.out.println(" In InterceptorClass Invoke the method in: before()");
}
public void after() {
System.out.println(" In InterceptorClass Invoke the method in: after()");
}
}
4. Create an agent
public class DynamicProxyHandler {
// Declare a proxy object
private Object target;
// Create an interceptor
InterceptorClass interceptor = new InterceptorClass();
// Dynamic generation 1 Proxy objects, and bound to the proxy class and proxy handler
public Object getProxyInstance(final Object target) {
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
interceptor.before();
Object result = method.invoke(target, args);
interceptor.after();
return result;
}
});
}
}
Under Test 1:
public class UserDaoImpl implements IUserDao {
public void save() {
System.out.println("-------- Data has been saved ---------");
}
}
0
Output:
Invoke method in InterceptorClass: before ()
Call the doSomething method in the business component BusinessClass
Invoke method in InterceptorClass: after ()