What is the dynamic proxy?
Under the first static proxy:
That is, before the program is run, has been compiled classes, this is a static agents,
Dynamic Agent:
That is, before the program run, the proxy class does not exist, but the program is running, a dynamic class is dynamically generated proxy class.
There may be the following thought
Proxy mode What? What technology?
Why use a proxy model? What are the benefits?
Dynamic proxy scenarios What?
Let us talk about dynamic proxy that implements it:
The main dynamic proxy using Java reflection technology:
JavaAPI concerning InvocationHandler so there is generally a description of each agent class must implement this interface InvocationHandler, will be associated with each agent class to a handle,
When a proxy class method calls will go to the Invoke method InvocationHandler the call.
The following code is the code references that cattle
InvocationHandler look at the source code, I'll no longer write it again.
public interface InvocationHandler
{
public abstract Object invoke(Object obj, Method method, Object aobj[])
throws Throwable;
}
Invoke this method has several parameters:
obj: we represent real objects to call
method: indicates that a real object of our method to invoke.
aobj []: representation of a real object method accepts parameters.
How to use this InvocationHandler this interface, mainly to see the proxy class:
Proxy is to create a proxy object of the class
Proxy This class has a method to this: is the most used method
public static Object newProxyInstance(ClassLoader classloader, Class aclass[], InvocationHandler invocationhandler)
throws IllegalArgumentException
parameter:
classloader: definition of the object loaded by the ClassLoader
aclass []: which is to provide an interface for the proxy object that represents the proxy object implements these interfaces,
invocationhandler: that he would associate the proxy method call to an object invocationhandler
The main dynamic proxy class by Proxy interface invocationhandler:
Look at specific dynamic proxy to achieve a better understanding:
1. First is certainly a need for interfaces:
public interface UserService {
public String getName(int id);
public Integer getAge(int id);
}
Also we need to implement this interface, which is the proxy object:
public class UserServiceImpl implements UserService {
@Override
public String getName(int id) {
System.out.println("------getName------");
return "Tom";
}
@Override
public Integer getAge(int id) {
System.out.println("------getAge------");
return 10;
}
}
Also you need to customize a invocationhandler, to realize his invoke methods:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
private Object target;
MyInvocationHandler() {
super();
}
MyInvocationHandler(Object target) {
super();
this.target = target;
}
@Override
public Object invoke(Object o, Method method, Object[] args) throws Throwable {
if("getName".equals(method.getName())){
System.out.println("++++++before " + method.getName() + "++++++");
Object result = method.invoke(target, args);
System.out.println("++++++after " + method.getName() + "++++++");
return result;
}else{
Object result = method.invoke(target, args);
return result;
}
}
}
Finally, look at how the proxy is to use this interface, as well as the invocationhandler
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class TestProxy {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
InvocationHandler invocationHandler = new MyInvocationHandler(userService);
UserService userServiceProxy = (UserService)Proxy.newProxyInstance(userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(), invocationHandler);
System.out.println(userServiceProxy.getName(1));
System.out.println(userServiceProxy.getAge(1));
}
}
Can be seen more clearly understood newproxyInstance is used to generate the proxy proxy object, userService is directed to a particular implementation
UserServiceImpl
NewproxyInstance method to pass the actual classLoader, invocationhandler interfaces, and call the class method corresponds to the actual class can be realized:
System.out.println("++++++before " + method.getName() + "++++++");
In fact, this line of code above have *** properties, and then discuss in detail aop time.
This can be seen above use reflective technology to achieve dynamic proxy, we need to define an interface, but sometimes really do not want to define interfaces, can only hope to achieve a good definition of the class, and then you run before the method, after running add some content can be.
This would be considered a good use of this, but CGLIB CGLIB dynamic proxy is very convenient.
ASM uses Cglib bytecode technology to generate using the proxy class bytecode. Higher efficiency than the reflection, but the agent is not self final class, clglib elements are integrated proxy class. final class can not be inherited.
The following look cglib concrete realization:
Download cglib asm package and package your project need to rely on these two packages:
First we need a non-final class, and no longer require an interface of reflex
public class StudentService {
public String getName(){
System.out.println("------getName------");
return "Tom";
}
public Integer getID(){
System.out.println("------getID------");
return 10;
}
}
Then look at how the agency above class, you need to define an interceptor:
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibProxy implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
System.out.println("++++++before " + methodProxy.getSuperName()
+ "++++++");
System.out.println(method.getName());
Object o1 = methodProxy.invokeSuper(o, args);
System.out.println("++++++before " + methodProxy.getSuperName()
+ "++++++");
return o1;
}
}
Interceptf similar to the above method and invoke methods invocationhandler in by interceptf to really call the method invokeSuper:
Finally, look Cglb specifically how this class proxy StudentService it:
import net.sf.cglib.proxy.Enhancer;
public class TestCglib {
public static void main(String[] args) {
CglibProxy cglibProxy = new CglibProxy();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(StudentService.class);
enhancer.setCallback(cglibProxy);
StudentService o = (StudentService)enhancer.create();
System.out.println(o.getName());
// System.out.println(o.getID());
}
}
O above that is a proxy class that can access real Studentservice method:
The result: Wuxi gynecological check how much money http://www.120csfkyy.com/
++++++before CGLIB$getName$1++++++
getName
------getName------
++++++before CGLIB$getName$1++++++
Tom
Use Cglib so what benefit?
Look at the code below:
public class TestCglib {
public static void main(String[] args) {
CglibProxy cglibProxy = new CglibProxy();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(StudentService.class);
enhancer.setCallback(cglibProxy);
StudentService o = (StudentService)enhancer.create();
System.out.println(o.getName());
// System.out.println(o.getID());
Enhancer enhancer1 = new Enhancer();
enhancer1.setSuperclass(UserServiceImpl.class);
enhancer1.setCallback(cglibProxy);
UserServiceImpl obj = (UserServiceImpl)enhancer1.create();
System.out.println(obj.getName(1));
// System.out.println(o.getID());
}
}
Just write a
cglibProxy
Can be achieved
UserServiceImpl proxy for the StudentService
Reducing the tedious code, so there is only one agent is enough, followed by easy maintenance, decoupling, if there is a problem, as long as the original class to go on it