After a single example of the experience of sharing, today to talk about the second design mode, on the agent model of personal understanding. Agent you can think of it as a middleman, intermediary, etc., do not need you personally to deal with what you want to do, you want to tell them, let them to help you achieve, completed and then the final results to inform you.
Generally speaking, agent mode is divided into two kinds: static proxy and dynamic proxy.
So first, let's say static proxies:
Static proxy
A static proxy needs to define an interface (Interface) or a parent class when used, and the object being represented implements the same interface as the proxy object or inherits the same parent class.
Here's a case:
Interface
/** *
Proxy interface
* @author lyr
* @date November 27, 2017 * * Public
interface Iuserdao {
void Save ();
}
Target object (demand side, commonly known as customer side)
/**
* target Object Implementation Interface
* @author lyr
* @date November 27, 2017/public
class Userdao implements Iuserdao c13/>public void Save () {
System.out.println ("Data is being saved ..... ");
SYSTEM.OUT.PRINTLN ("Data saved successfully!");
}
Proxy object (intermediary, agent)
/**
* Proxy object, static agent
* @author lyr
* @date November 27, 2017/public
class Userdaoproxy implements iuserdao{
//Receive Save target object
private Iuserdao Iuserdao;
Public Userdaoproxy (Iuserdao Iuserdao) {
This.iuserdao = Iuserdao;
}
public void Save () {
System.out.println ("Open transaction ...");
Iuserdao.save (); Execute target object method
System.out.println ("Commit transaction ...");
}
Test
/**
* Test class
* @author lyr
* @date November 27, 2017 * * Public
class Testproxy {public
static void Main (string[] args) {
//target object (customer)
Userdao Userdao = new Userdao ();
Proxy object (intermediary), the target object passed to the proxy object, establish agent relationship
Userdaoproxy proxy = new Userdaoproxy (Userdao);
Execute Proxy method
Proxy.save ();
}
Advantages and disadvantages of static agents:
Advantages: It can extend the target object without modifying the function of target object;
Disadvantage: The target object to implement the same interface as the proxy object, will produce too many proxy classes, and once the interface changes to change or increase the method, then the target object and proxy objects need to be maintained.
Dynamic Proxy
For static agent problems, can be solved by dynamic proxy. So what are the special places for dynamic proxies? In fact, there are two options for dynamic proxies (JDK dynamic proxies and cglib dynamic proxies).
1.1JDK Dynamic Proxy
Several features of JDK dynamic proxy:
(1) The proxy object does not need to implement the interface;
(2) Proxy object generation, is the use of JDK API, dynamic in memory to build proxy objects. (Requires us to specify the type of interface to create the proxy object/target object implementation);
(3) The JDK proxy is also called Interface agent.
JDK generates the API for proxy objects
Agent Class Package: Java.lang.reflect.Proxy
Let's take a look at the code implementation example:
/**
* Create dynamic proxy objects
* Dynamic proxies do not need to implement interfaces. However, you need to specify the interface type
* @author lyr
* @date November 27, 2017
/Public
class Proxyfactory {
//Maintain a target object
Private Object target;
Public proxyfactory (Object target) {
this.target=target
}
Generates a proxy object for the target object
getproxyinstance () {return proxy.newproxyinstance () (
target.getclass). getClassLoader (),
Target.getclass (). Getinterfaces (),
new Invocationhandler () {public
Object invoke (Object Proxy, Method method, object[] args) throws exception{
System.out.println ("Start transaction ...");
Execute target object Method object
returnvalue = Method.invoke (target, args);
SYSTEM.OUT.PRINTLN ("Commit transaction ...");
Return returnvalue
}}
);
}
Test code
Target object
Iuserdao Iuserdao = new Userdao ();
Create a proxy object for the target object
iuserdao target = (Iuserdao) new Proxyfactory (Iuserdao). Getproxyinstance ();
Execute Proxy method
Target.save ();
The above example can be seen that the JDK dynamic proxy in the proxy object does not need to implement the interface, but the target object must implement the interface, otherwise it can not implement dynamic proxy. What is this, the problem is still there, but less. Of course, there is another dynamic proxy mode: Cglib dynamic agent.
1.2 Cglib Dynamic Agent
Cglib dynamic Proxy, also called a subclass proxy, constructs a subclass object in memory to extend the function of the target object.
(1) The JDK dynamic Proxy has a restriction, is the dynamic proxy object must realize one or many interfaces, otherwise needs to consider cglib dynamic proxy to realize;
(2) Cglib is a powerful and High-performance code generation package that can extend Java classes and implement Java interfaces during runtime. This can be seen in spring AOP and can be well intercepted;
(3) The bottom of the cglib is to convert the bytecode and generate new classes by using a small, fast byte code to process the framework ASM. There is no incentive to use ASM directly, which requires you to be familiar with the internal structure of the JVM, including the format of the class file and the instruction set.
In fact, there is also a need to note that: (1) The proxy class can not be final modified, otherwise it will be directly to the error; (2) If the method in the target object is final or static modified, it will not be intercepted.
When using a cglib dynamic proxy, you need to introduce its jar pack to use it, but the current spring core package already includes cglib related functionality (Spring is a bit wide), so just introduce the Spring-core-4.2.2.jar. Next, the following related code:
Look at the target object first, without implementing any interfaces
/**
* Target object, does not implement any interface
* @author lyr
* @date November 27, 2017/public
class Usersdao {public
void Save () {
System.out.println ("Saving data ...");
SYSTEM.OUT.PRINTLN ("Data saved successfully!");
}
Then look at the corresponding Cglib sub-class agent factory
/**
* Cglib sub-class agent factory, Userdao in memory dynamic construction of a subclass object
* @author lyr
* @date November 27, 2017 * *
public
class Proxyfactorys implements methodinterceptor{
private Object target;
Public Proxyfactorys (Object target) {
this.target = target;
}
Public Object getproxyinstance () {
//This is a tool class that allows you to create a Java proxy for a non-interface type, dynamically create subclasses of a given type, and intercept all methods
enhancer en = new Enhancer ();
En.setsuperclass (Target.getclass ());
En.setcallback (this);
return En.create ();
}
Public Object intercept (object obj, Method method, object[] Args,methodproxy proxy) throws Throwable {
System.out.pr Intln ("Start transaction ...");
Object returnvalue = Method.invoke (target, args);
SYSTEM.OUT.PRINTLN ("Commit transaction ..."); return returnvalue
}
}
The final Test
/**
* Test class
* @author lyr
* @date November 27, 2017 * * Public
class Testproxy {public
static void Main (S) Tring[] args {
Usersdao Userdao = new Usersdao ();
Usersdao target = (Usersdao) new Proxyfactorys (Userdao). Getproxyinstance ();
Target.save ();
}
Here you can see that it and the JDK agent is also a bit similar, of course, these two dynamic agents to use in accordance with the specific circumstances, in general, in spring AOP, if the object of the added container is implemented interface, use JDK dynamic proxy, otherwise, Use cglib dynamic Proxy.
Agent mode just say so much, thank you, next goodbye.