This section highlights:
- Java static proxy
- JDK Dynamic Agent
1 problems encountered in object-oriented design thinking
In traditional OOP programming, the object is the core, and through the collaboration between the objects to form a complete software function, because the object can inherit, so we can have the same function or the same characteristics of the attributes of the abstract into a hierarchical class structure system. With the continuous expansion of software specifications, specialization of division of labor more and more series, as well as the increasing number of application practices of OOP, it also exposes some problems that OOP can not be solved very well.
Now assume that the system has three pieces of exactly similar code, the code will usually be "copy", "Paste" to complete the way, the software developed in this way:
Perhaps the reader has discovered the shortcomings of this approach, and if one day the blue background code needs to be modified,
Do you want to change three places at the same time? If not only these three places contain this code, but 100
, or even 1000 places, what would that be?
Logging is everywhere in the code---take a look at an example:
In order to keep track of the running process of an application, many methods require logging information. We generally write this:
//log4j use See the article "Log4j Introduction"ImportOrg.apache.log4j.Logger; Public classPerson {PrivateLogger Logger = Logger.getlogger (person.class); Public voidsleep () {logger.info ("Start Execution time:"+NewDate ()); System.out.println ("Sleeping in"); Logger.info ("Execution End time:"+NewDate ()); } Public voideating () {Logger.info ("Start Execution Time:" + new Date () "); System.out.println ("Being in the middle of a meal"); Logger.info ("Execution End time:" + new Date () "); }}
question: where is the disadvantage?
- L CONFUSED the responsibility of the business method itself
- • Great maintenance effort
2 Solution Static proxy
- L goal is to completely separate the business code from the log code to achieve loose coupling.
- The proxy object and the Proxied object must implement the same interface, implement the service related to logging in the proxy object, and call the Proxied object when needed, while the proxy object retains only the business code.
Implementation of static Proxy
1) Define the interface:
Public Interface IPerson { publicabstractvoid sleep (); Public Abstract void eating ();}
2) by proxy class
Public class Implements IPerson { publicvoid sleep () { System.out.println ("sleeping in"); } publicvoid eating () { System.out.println ("eating in");} }
3) proxy class
ImportOrg.apache.log4j.Logger; Public classPersonproxyImplementsIPerson {PrivateIPerson person; PrivateLogger Logger = Logger.getlogger (personproxy.class); Publicpersonproxy (IPerson person) { This. person =Person ; } Public voideating () {Logger.info ("Start Execution Time:" + new Date () "); Person.eating (); Logger.info ("Execution End time:" + new Date () "); } Public voidsleep () {Logger.info ("Start Execution Time:" + new Date () "); Person.sleep (); Logger.info ("Execution End time:" + new Date () "); }}
4) Test class
Package Com.aptech.aop2; Public class persontest { publicstaticvoid main (string[] args) { new Personproxy (new Person ()); Proxy.eating (); Proxy.sleep (); }}
Disadvantages of static proxies:
A proxy interface can serve only one type of object. It's not up to a bigger project at all.
3 Solutions Dynamic Agent
- After JDK1.3, we have added dynamic agent functions that can assist in development. Instead of writing specific proxy objects for specific objects and methods, using dynamic proxies allows a processor (Handler) to serve individual objects.
- The class design of a processor must implement the Java.lang.reflect.InvocationHandler interface.
- A dynamic proxy implemented by the Invocationhandler interface can only be a proxy interface implementation class.
Dynamic Proxy Implementation
1) Processor (Handler)
Public classDynaproxyhandlerImplementsInvocationhandler {PrivateLogger Logger = Logger.getlogger (Dynaproxyhandler.class); PrivateObject Target;//The object being proxied Public voidsettarget (Object target) { This. target =Target; } Publicobject Invoke (Object proxy, Method method, object[] args)throwsthrowable {logger.info ("Execution start time:" +NewDate ()); Object result=Method.invoke (target, args); Logger.info ("Execution End time:" +NewDate ()); returnResult//return method Execution result }}
2) factory where the agent object is produced
Import Java.lang.reflect.Proxy; Public class dynaproxyfactory { //obj is a proxy object public static Object GetProxy (Object obj) { new Dynaproxyhandler (); Handler.settarget (obj); return proxy.newproxyinstance (Obj.getclass (). getClassLoader (), Obj.getclass (). Getinterfaces (), handler);} }
3) Test class
Public class persontest { publicstaticvoid main (string[] args) { = (IPerson ) Dynaproxyfactory.getproxy (new Person ()); // returns the proxy class, a proxy class that is dynamically created in memory by the JVM, which implements all the interfaces of an incoming interface array (all methods). person.eating (); Person.sleep (); }}
Spring static agents and dynamic agents