Implement a configurable AOP framework similar to Spring
Two important classes in the configurable AOP framework:
BeanFactory
BeanFactory of the factory class is responsible for creating instance objects of the target or proxy class and switching through the configuration file. The getBean () method returns an Instance Object Based on the parameter string, if the corresponding class name of the parameter string in the configuration file is not ProxyFactoryBean (according to this example), the Instance Object of the class is directly returned; otherwise, the object returned by the getProxy () method of the Instance Object of the class is returned.
BeanFactory constructor receives the input stream object representing the configuration file. The configuration file format is as follows:
# Xxx = java. util. ArrayList is not a ProxyFactoryBean class
Xxx = cn. test. ProxyFactoryBean
Xxx.tar get = java. util. ArrayList # target class.
Xxx. advice = cn. test. Myadvice # system method class. Add a custom method to the target class
ProxyFactoryBean
A factory that acts as an encapsulation to generate a dynamic proxy must provide the following for the factory:
1. target object)
2. System Method Class Object (Advice)
Write Client Applications
1. Write classes that implement the Advice interface and configure them in the configuration file.
2. Call BeanFactory to get the object
Code Implementation
1. Write the Advice Interface Class
/** System function interface class */public interface Advice {void beforMethod (); // system function method before the target method (only the target method is passed, target, method, and args parameter can be passed. void afterMethod (Method method); // system function method after the target Method}
2. Implement the Advice Interface
/** Class implementing System function interfaces */public class MyAdvice implements Advice {private long startTime = 0; @ Overridepublic void beforMethod () {System. out. println ("---- System method before calling the target method"); startTime = System. currentTimeMillis () ;}@ Overridepublic void afterMethod (Method method) {System. out. println ("---- System method after the target method is called"); long endTime = System. currentTimeMillis (); System. out. println (method. getName () + "execution time:" + (endTime-startTime ));}}
3. Compile the configuration file config. properties.
# Xxx = java. util. ArrayListxxx = com. test. aopframework. ProxyFactoryBean # class xxx. Advice = com. test. proxy. MyAdvice
# Configure the target class xxx.tar get = java. util. ArrayList for proxy
4. BeanFactory class (create an Instance Object of the target class or proxy class)
/** JavaBean class */public class BeanFactory {Properties props = new Properties (); // configure. property file, retrieve the value public BeanFactory (InputStream ips) {try {props. load (ips);} catch (IOException e) {e. printStackTrace () ;}} public Object getBean (String name) {String propertyName = props. getProperty (name); // retrieve the configuration file property value Object bean = null; try {Class clazz = Class. forName (propertyName); // obtain the bytecode bean = clazz for the attribute value. newInstance ();} catch (Exception e) {e. printStackTrace () ;}// obtain the instance Object if (bean instanceof ProxyFactoryBean) {Object proxy = null; try {export ProxyFactoryBean = (proxyFactoryBean) bean; Advice advice = (Advice) Class. forName (String) props. getProperty (name + ". advice ")). newInstance (); Object target = Class. forName (props. getProperty (name + ". target ")). newInstance (); proxyFactoryBean. setAdvice (advice); // sets the system method Class Object proxyFactoryBean of the proxy object class. setTarget (target); // set proxy object proxy = proxyFactoryBean. getProxy (); // get the proxy object} catch (Exception e) {// TODO Auto-generated catch blocke. printStackTrace ();} return proxy;} return bean ;}}
5. ProxyFactoryBean (Act as the factory for encapsulating and generating dynamic proxies)
/** Act as the factory for encapsulating and generating dynamic proxies */public class ProxyFactoryBean {private Advice advice; // defines the private Object target of the system method class Object; // define the target object public Advice getAdvice () {return advice;} public void setAdvice (Advice advice) {this. advice = advice;} public Object getTarget () {return target;} public void setTarget (Object target) implements this.tar get = target;} public Object getProxy () {// create Proxy method return (Object) Proxy. newProxyInstance (ta Rget. getClass (). getClassLoader (), // implements the same class loader as the target object. getClass (). getInterfaces (), // implements the same interface as the target object. new InvocationHandler () {@ Override // proxy: represents the proxy object method: represents the method called by the proxy object args: public Object invoke (Object proxy, Method method, Object [] args) throws Throwable {advice. beforMethod (); Object retVal = method. invoke (target, args); // reflection mechanism, call the method advice of the target object. afterMethod (method); // pass The target // return object will be returned to the proxy. Return retVal ;}});}}
6. Write Client Applications
/** Compile the client application aop framework */public class ClientAopFrameWork {public static void main (String [] args) {InputStream ips = ClientAopFrameWork. class. getResourceAsStream ("config. properties "); Object bean = new BeanFactory (ips ). getBean ("xxx"); System. out. println (bean );}}