I have previously written a simple IOC container. This AOP function is added to this
Write Intercept class to inherit InvocationHandler
Public class Intercept implements InvocationHandler {
/**
* The object to be processed (that is, the object with the business logic before and after the method, such as Hello in the example)
*/
Private Object target; // the target Object to be proxy
/**
* Objects processed by the dynamic generation method (fixed syntax)
* Target (class methods to be concerned)
*/
Public Object bind (Object target) throws InstantiationException, IllegalAccessException
{
This.tar get = target;
Return Proxy.newProxyInstance(this.tar get. getClass (). getClassLoader (), this.tar get. getClass (). getInterfaces (), this );
}
@ Override
Public Object invoke (Object proxy, Method method, Object [] args)
Throws Throwable {
Object result;
AOPModel model = null;
If (InterceptList. getInterceptMethod (). containsKey (method. getName ()))
{
Model = InterceptList. getInterceptMethod (). get (method. getName ());
This. monitor (model. getBefore (), model.getbefore_aspectname(,,this.tar get );
Result = method.invoke(this.tar get, args );
This. monitor (model. getAfter (), model.getafter_aspectname(,,this.tar get );
} Else {
Result = method.invoke(this.tar get, args );
}
Return result;
}
/**
* Determine before and after calls based on whether to inject cross-cutting concerns
*/
Private void monitor (Object clazz, String aspectName, Object target) throws Exception {
If (clazz! = Null ){
Method [] methods = clazz. getClass (). getDeclaredMethods ();
For (Method method: methods ){
If (method. getName (). equals (aspectName )){
Method. invoke (clazz, target );
}
}
}
}
}
Then modify our IOC container: After the user inherits the IOC container, it automatically finds the parameters configured by the user for initialization.
Note: use this, new Intercept (). bind () Load object
Public class IOC {
Public IOC ()
{
Init ();
}
Public void Init ()
{
Field [] fields = getClass (). getDeclaredFields ();
For (Field field: fields ){
Inject inject = field. getAnnotation (Inject. class );
Try {
If (inject! = Null)
{
Field. setAccessible (true );
If (inject. Intercept ())
{
Field. set (this, new Intercept (). bind (Class. forName (inject. ClassName (). trim (). newInstance ()));
} Else {
Field. set (this, Class. forName (inject. ClassName (). trim (). newInstance ());
}
}
} Catch (Exception e ){
Logger. getLogger (getClass (). error ("initialization container exception:" + inject. ClassName (). trim () + "initialization failed", e );
}
}
}
}
Test class
Package com. metarnet. Main;
Import com. metarnet. Injects. Inject;
Import com. metarnet. Interfaces. BeforeAfter;
Import com. metarnet. Interfaces. Interface1;
Import com. metarnet. extend. AOPModel;
Import com. metarnet. extend. IOC;
Import com. metarnet. extend. IOCInit;
Import com. metarnet. extend. InterceptList;
Public class TestIOC extends IOC {
Public TestIOC (){
Super ();
}
@ Inject (ClassName = "com. metarnet. Interfaces. imps. Interface1Impl", Intercept = true)
Private Interface1 interface1;
@ Inject (ClassName = "com. metarnet. Interfaces. imps. Interface1Impl2", Intercept = false)
Private Interface1 interface2;
@ Inject (ClassName = "com. metarnet. Interfaces. imps. After", Intercept = false)
Private BeforeAfter;
@ Inject (ClassName = "com. metarnet. Interfaces. imps. Before", Intercept = false)
Private BeforeAfter before;
Public Interface1 getInterface1 (){
Return interface1;
}
Public void setInterface1 (Interface1 interface1 ){
This. interface1 = interface1;
}
/**
* This method can be modified to read the configuration file and then initialize
*/
Public void init ()
{
AOPModel model = new AOPModel ();
Model. setAfter (after );
Model. setBefore (before );
Model. setAfter_aspectName ("SayAfter ");
Model. setBefore_aspectName ("SayBefore ");
InterceptList. getInterceptMethod (). put ("SayHello", model );
InterceptList. getInterceptList (). add ("interface1 ");
}
Public static void main (String [] args ){
IOCInit. Init ();
TestIOC ioc = new TestIOC ();
Ioc. init ();
Ioc. interface1.SayHello ();
Ioc. interface2.SayHello ();
}
}
Model
/**
* List of cross-cutting requests
*/
Public class AOPModel {
Private Object before; // before cross-cutting concern (previously called)
Private Object after; // after (called later)
Private String before_aspectName; // method of before cross-cutting call
Private String after_aspectName; // method of calling after
Public Object getBefore (){
Return before;
}
Public void setBefore (Object before ){
This. before = before;
}
Public Object getAfter (){
Return after;
}
Public void setAfter (Object after ){
This. after = after;
}
Public String getBefore_aspectName (){
Return before_aspectName;
}
Public void setBefore_aspectName (String before_aspectName ){
This. before_aspectName = before_aspectName;
}
Public String getAfter_aspectName (){
Return after_aspectName;
}
Public void setAfter_aspectName (String after_aspectName ){
This. after_aspectName = after_aspectName;
}
}
/**
* List of methods to be monitored
*/
Public final class InterceptList {
Private static HashMap <String, AOPModel> map = new HashMap <String, AOPModel> ();
Private static ArrayList <String> list = new ArrayList <String> ();
Public static HashMap <String, AOPModel> getInterceptMethod (){
Return map;
}
Public static ArrayList <String> getInterceptList ()
{
Return list;
}
}