AspectJ是什麼?AspectJ能幹什麼?AspectJ是怎麼幹活的?html
AspectJ是什麼java
AspectJ是一個代碼生成工具(Code Generator)。
AspectJ語法就是用來定義代碼生成規則的語法。您若是使用過Java Compiler Compiler (JavaCC),您會發現,二者的代碼生成規則的理念驚人類似。
AspectJ有本身的語法編譯工具,編譯的結果是Java Class文件,運行的時候,classpath須要包含AspectJ的一個jar文件(Runtime lib)。
AspectJ和xDoclet的比較。AspectJ和EJB Descriptor的比較。app
AspectJ能幹什麼?工具
AOP是Object Oriented Programming(OOP)的補充。
OOP可以很好地解決對象的數據和封裝的縱向問題,卻不能很好的解決Aspect("方面")分離的橫向問題ui
使用價值this
認證、事務、日誌等等spa
如:你已經寫好一個功能,有一天客戶提出一個需求,須要對調用這個服務的用戶進行權限認證,這時候經過AspectJ實現一個AOP是你的首選。日誌
AspectJ是怎麼幹活的?code
背景:定義一個Class,若是須要對這個Class的get和set方法進行進行切入htm
實現方案:
1、定義aj規則文件,經過調用call方法實現around切入
2、定義aj規則文件,經過調用execution方式實現around切入
過程:定義一個Class,定義一個編譯規則,而後反編譯class咱們看工做過程
實現原理:經過定義aj規則文件,由AspectJ編譯器掃描包內的aj文件進行規則讀取,而後對java代碼進行包裝後編譯成class文件,這個class文件能夠被AspectJ的runtime識別並工做,因此在使用AspectJ時必定要引入aspectj.runtime包
方案一:定義aj規則文件,經過調用call方法實現around切入
Object1.java
package bean; public class Object1 { private int x=1; public int getInfo(){ return this.x; } public void setInfo(int x){ this.x=x; } }
Demo1BoundObject1.aj
package bean; aspect Demo1BoundObject1 { pointcut setter(Object1 object1): call(void Object1.set*(*))&&target(object1); void around(Object1 object1): setter(object1){ String name = thisJoinPointStaticPart.getSignature().getName(); System.out.println("before :" + name); proceed(object1); System.out.println("after :" + name); } pointcut getter(Object1 object1): call(int Object1.get*())&&target(object1); int around(Object1 object1): getter(object1){ String name = thisJoinPointStaticPart.getSignature().getName(); System.out.println("before :" + name); return proceed(object1); } }
Demo1.java
package bean; public class Demo1 { public static void main(String[] args){ Object1 obj=new Object1(); obj.setInfo(2); obj.getInfo(); } }
進行反編譯:
Demo1.class
// Decompiled by DJ v3.11.11.95 Copyright 2009 Atanas Neshkov Date: 2014/7/4 16:12:27 // Home Page: http://members.fortunecity.com/neshkov/dj.html http://www.neshkov.com/dj.html - Check often for new version! // Decompiler options: packimports(3) // Source File Name: Demo1.java package bean; import java.io.PrintStream; import org.aspectj.lang.Signature; import org.aspectj.runtime.internal.AroundClosure; import org.aspectj.runtime.reflect.Factory; // Referenced classes of package bean: // Object1, Demo1BoundObject1 public class Demo1 { public Demo1() { } public static void main(String args[]) { Object1 obj = new Object1(); byte byte0 = 2; Object1 object1 = obj; setInfo_aroundBody1$advice(object1, byte0, Demo1BoundObject1.aspectOf(), object1, null, ajc$tjp_0); Object1 object1_1 = obj; getInfo_aroundBody3$advice(object1_1, Demo1BoundObject1.aspectOf(), object1_1, null, ajc$tjp_1); } private static final void setInfo_aroundBody0(Object1 object1, int i) { object1.setInfo(i); } private static final void setInfo_aroundBody1$advice(Object1 target, int x, Demo1BoundObject1 ajc$aspectInstance, Object1 object1, AroundClosure ajc$aroundClosure, org.aspectj.lang.JoinPoint.StaticPart thisJoinPointStaticPart) { String name = thisJoinPointStaticPart.getSignature().getName(); System.out.println((new StringBuilder("before :")).append(name).toString()); AroundClosure aroundclosure = ajc$aroundClosure; Object1 object1_1 = object1; setInfo_aroundBody0(object1_1, x); System.out.println((new StringBuilder("after :")).append(name).toString()); } private static final int getInfo_aroundBody2(Object1 object1) { return object1.getInfo(); } private static final int getInfo_aroundBody3$advice(Object1 target, Demo1BoundObject1 ajc$aspectInstance, Object1 object1, AroundClosure ajc$aroundClosure, org.aspectj.lang.JoinPoint.StaticPart thisJoinPointStaticPart) { String name = thisJoinPointStaticPart.getSignature().getName(); System.out.println((new StringBuilder("before :")).append(name).toString()); AroundClosure aroundclosure = ajc$aroundClosure; Object1 object1_1 = object1; return getInfo_aroundBody2(object1_1); } private static void ajc$preClinit() { Factory factory = new Factory("Demo1.java", bean/Demo1); ajc$tjp_0 = factory.makeSJP("method-call", factory.makeMethodSig("1", "setInfo", "bean.Object1", "int", "x", "", "void"), 8); ajc$tjp_1 = factory.makeSJP("method-call", factory.makeMethodSig("1", "getInfo", "bean.Object1", "", "", "", "int"), 9); } private static final org.aspectj.lang.JoinPoint.StaticPart ajc$tjp_0; /* synthetic field */ private static final org.aspectj.lang.JoinPoint.StaticPart ajc$tjp_1; /* synthetic field */ static { ajc$preClinit(); } }
Object1.class
// Decompiled by DJ v3.11.11.95 Copyright 2009 Atanas Neshkov Date: 2014/7/4 16:14:31 // Home Page: http://members.fortunecity.com/neshkov/dj.html http://www.neshkov.com/dj.html - Check often for new version! // Decompiler options: packimports(3) // Source File Name: Object1.java package bean; public class Object1 { public Object1() { x = 1; } public int getInfo() { return x; } public void setInfo(int x) { this.x = x; } private int x; }
方案2、定義aj規則文件,經過調用execution方式實現around切入
Demo1.java
package bean; public class Demo1 { public static void main(String[] args){ Object1 obj=new Object1(); obj.setInfo(2); obj.getInfo(); } }
Object1.java
package bean; public class Object1 { private int x=1; public int getInfo(){ return this.x; } public void setInfo(int x){ this.x=x; } }
Demo1BoundObject1.aj
package bean; aspect Demo1BoundObject1 { pointcut bankMethods(Object1 object1) : (execution (* Object1.get*()) || execution (* Object1.set*(*)))&&target(object1); Object around(Object1 object1): bankMethods(object1) { // 驗證account是否爲合法用戶 String name = thisJoinPointStaticPart.getSignature().getName(); System.out.println("bankMethods before :" + name); Object result = proceed(object1); return result; } }
Demo1.class
// Decompiled by DJ v3.11.11.95 Copyright 2009 Atanas Neshkov Date: 2014/7/4 16:22:53 // Home Page: http://members.fortunecity.com/neshkov/dj.html http://www.neshkov.com/dj.html - Check often for new version! // Decompiler options: packimports(3) // Source File Name: Demo1.java package bean; // Referenced classes of package bean: // Object1 public class Demo1 { public Demo1() { } public static void main(String args[]) { Object1 obj = new Object1(); obj.setInfo(2); obj.getInfo(); } }
Object1.class
// Decompiled by DJ v3.11.11.95 Copyright 2009 Atanas Neshkov Date: 2014/7/4 16:23:17 // Home Page: http://members.fortunecity.com/neshkov/dj.html http://www.neshkov.com/dj.html - Check often for new version! // Decompiler options: packimports(3) // Source File Name: Object1.java package bean; import java.io.PrintStream; import org.aspectj.lang.Signature; import org.aspectj.runtime.internal.AroundClosure; import org.aspectj.runtime.internal.Conversions; import org.aspectj.runtime.reflect.Factory; // Referenced classes of package bean: // Demo1BoundObject1 public class Object1 { public Object1() { x = 1; } public int getInfo() { return Conversions.intValue(getInfo_aroundBody1$advice(this, Demo1BoundObject1.aspectOf(), this, null, ajc$tjp_0)); } public void setInfo(int x) { int i = x; setInfo_aroundBody3$advice(this, i, Demo1BoundObject1.aspectOf(), this, null, ajc$tjp_1); } private static final int getInfo_aroundBody0(Object1 ajc$this) { return ajc$this.x; } private static final Object getInfo_aroundBody1$advice(Object1 ajc$this, Demo1BoundObject1 ajc$aspectInstance, Object1 object1, AroundClosure ajc$aroundClosure, org.aspectj.lang.JoinPoint.StaticPart thisJoinPointStaticPart) { String name = thisJoinPointStaticPart.getSignature().getName(); System.out.println((new StringBuilder("bankMethods before :")).append(name).toString()); AroundClosure aroundclosure = ajc$aroundClosure; Object1 object1_1 = object1; Object result = Conversions.intObject(getInfo_aroundBody0(object1_1)); return result; } private static final void setInfo_aroundBody2(Object1 ajc$this, int x) { ajc$this.x = x; } private static final Object setInfo_aroundBody3$advice(Object1 ajc$this, int x, Demo1BoundObject1 ajc$aspectInstance, Object1 object1, AroundClosure ajc$aroundClosure, org.aspectj.lang.JoinPoint.StaticPart thisJoinPointStaticPart) { String name = thisJoinPointStaticPart.getSignature().getName(); System.out.println((new StringBuilder("bankMethods before :")).append(name).toString()); AroundClosure aroundclosure = ajc$aroundClosure; Object1 object1_1 = object1; setInfo_aroundBody2(object1_1, x); Object result = null; return result; } private static void ajc$preClinit() { Factory factory = new Factory("Object1.java", bean/Object1); ajc$tjp_0 = factory.makeSJP("method-execution", factory.makeMethodSig("1", "getInfo", "bean.Object1", "", "", "", "int"), 6); ajc$tjp_1 = factory.makeSJP("method-execution", factory.makeMethodSig("1", "setInfo", "bean.Object1", "int", "x", "", "void"), 11); } private int x; private static final org.aspectj.lang.JoinPoint.StaticPart ajc$tjp_0; /* synthetic field */ private static final org.aspectj.lang.JoinPoint.StaticPart ajc$tjp_1; /* synthetic field */ static { ajc$preClinit(); } }