Article Directory
Agent Model Description:
proxy (Proxy) is a design pattern that provides an additional way to access the target object; that is accessed by the target through a proxy object benefits of doing so are: On the basis of the target object can be achieved on additional enhancements. functional operation of the expansion of the target object's function.
use this programming to a thought: Do not feel free to go at someone or modify the code already written, if the need to change the modification, the method can be extended by way of proxy
For example: we can buy a house through a real estate agent to purchase, without the need to go directly to property developers to buy, which is our intermediary proxy object.
Proxy mode by category can be divided into three categories:
- Static agents
- Dynamic proxy
dynamic proxy can be divided into: jdk api dynamic proxy and proxy dynamic cglib
Static agents
When using static agent, need to define interfaces or parent class is the interface to achieve the same or the same parent is inherited along with the proxy object proxy object.
Code Example:
Proxy interface UserDao
package com.sl.proxy;
/**
* @author shuliangzhao
* @Title: UserDao
* @ProjectName spring-boot-learn
* @Description: TODO
* @date 2019/10/19 17:02
*/
public interface UserDao {
void delete();
}
Audience UserDaoImpl
package com.sl.proxy;
/**
* @author shuliangzhao
* @Title: UserDaoImpl
* @ProjectName spring-boot-learn
* @Description: TODO
* @date 2019/10/19 17:02
*/
public class UserDaoImpl implements UserDao {
@Override
public void delete() {
System.out.println("删除数据");
}
}
Proxy object UserDaoProxy
package com.sl.proxy;
/**
* 代理对象
* @author shuliangzhao
* @Title: UserDaoProxy
* @ProjectName spring-boot-learn
* @Description: TODO
* @date 2019/10/19 17:03
*/
public class UserDaoProxy implements UserDao {
private UserDao target;
public UserDaoProxy(UserDao target) {
this.target = target;
}
@Override
public void delete() {
System.out.println("开始操作");
target.delete();
System.out.println("结束操作");
}
}
Test class App
public class App {
public static void main(String[] args) {
UserDaoImpl userDao = new UserDaoImpl();
UserDaoProxy userDaoProxy = new UserDaoProxy(userDao);
userDaoProxy.delete();
}
}
Summary: call the proxy object method to invoke the target needs to be noted that the proxy object to the target object. Implement the same interface , and then call the target object by calling the same method of approach.
1. can be done in the function without modifying the target object, the target extensions.
2. Disadvantages: Because the proxy object needs to implement the same interface as the target object, and so many proxy class, class too much at the same time, once. Interface method for increasing the target object and proxy object must be maintained.
Dynamic Proxy
Dynamic characteristics of the agent:
1, proxy object, no need to implement the interface
2 to generate a proxy object, the JDK using the API, the dynamic proxy object constructed in memory
jdk generated proxy object
JDK implementation agent only need to use Proxy.newProxyInstance method, but this method requires three parameters, complete wording is:
static Object newProxyInstance(ClassLoader loader, Class<?>[]
interfaces,InvocationHandler h )
- ClassLoader loader ,: audience used to specify the current class loader, the loader is to obtain a fixed
- Class <?> [] Interfaces ,: type of target object implements an interface, use the generic way to confirm the type of
- InvocationHandler h: event processing, when the method of execution of the target object, the event handler method will be triggered, the current method will execute the target object as a parameter
The sample code
creates UserDaoInvocationHandler class that implements the interface InvocationHandler, this class holds a proxy object is an instance of target
package com.sl.jdkproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @author shuliangzhao
* @Title: UserDaoInvocationHandler
* @ProjectName spring-boot-learn
* @Description: TODO
* @date 2019/10/19 17:14
*/
public class UserDaoInvocationHandler implements InvocationHandler {
private Object target;
public UserDaoInvocationHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理执行" +method.getName() + "方法");
Object invoke = method.invoke(target, args);
return invoke;
}
}
Factory to create a proxy class
package com.sl.jdkproxy;
import java.lang.reflect.Proxy;
/**
* @author shuliangzhao
* @Title: ProxyFactory
* @ProjectName spring-boot-learn
* @Description: TODO
* @date 2019/10/19 17:19
*/
public class ProxyFactory {
//维护一个目标对象
private Object target;
public ProxyFactory(Object target){
this.target=target;
}
//给目标对象生成代理对象
public Object getProxyInstance() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),new UserDaoInvocationHandler(target));
}
}
Test class App
package com.sl.jdkproxy;
import com.sl.staticproxy.UserDao;
import com.sl.staticproxy.UserDaoImpl;
/**
* @author shuliangzhao
* @Title: App
* @ProjectName spring-boot-learn
* @Description: TODO
* @date 2019/10/19 17:22
*/
public class App {
public static void main(String[] args) {
UserDao userDao = new UserDaoImpl();
UserDao proxyInstance = (UserDao) new ProxyFactory(userDao).getProxyInstance();
System.out.println(proxyInstance.getClass());
// 执行方法 【代理对象】
proxyInstance.delete();
}
}
Summary: proxy object does not need to implement the interface, but the target object must implement the interface, or can not use dynamic proxies
Acting cglib
The above static and dynamic agent Proxy models are required to achieve the target object is a target object interface, but sometimes the target object is just a single object, and does not implement any interfaces, this time we can use the target object is a subclass agent class implements embodiment, this method is called: Cglib agent
Cglib is a powerful, high-performance code generator package, it can extend the java class are widely used and implemented in many AOP frame java interfaces at runtime, e.g. Spring. AOP and synaop, provides a method for their interception (interception)
using cglib proxy Note:
1. the agent class can not be final, otherwise an error
2. If the target object's method is final / static, then it will not be blocked, that is, the business method does not execute the target object additional
sample code:
the object being proxied UserDao
*/
public class UserDao {
public void delete() {
System.out.println("删除方法");
}
}
Factory to create a proxy class
public class ProxyFactory implements MethodInterceptor {
//维护目标对象
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
//给目标对象创建一个代理对象
public Object getProxyInstance() {
//1.工具类
Enhancer enhancer = new Enhancer();
//2.设置父类
enhancer.setSuperclass(target.getClass());
//3.设置回调函数
enhancer.setCallback(this);
//4.创建子类
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("开始事务...");
//执行目标对象的方法
Object returnValue = method.invoke(target, objects);
System.out.println("提交事务...");
return returnValue;
}
}
Test category
public class App {
public static void main(String[] args) {
UserDao userDao = new UserDao();
UserDao proxyInstance = (UserDao) new ProxyFactory(userDao).getProxyInstance();
proxyInstance.delete();
}
}