AspectJ是什么?AspectJ能干什么?AspectJ是怎么干活的?
AspectJ是什么
AspectJ是一个代码生成工具(Code Generator)。
AspectJ语法就是用来定义代码生成规则的语法。您如果使用过Java Compiler Compiler (JavaCC),您会发现,两者的代码生成规则的理念惊人相似。
AspectJ有自己的语法编译工具,编译的结果是Java Class文件,运行的时候,classpath需要包含AspectJ的一个jar文件(Runtime lib)。
AspectJ和xDoclet的比较。AspectJ和EJB Descriptor的比较。AspectJ能干什么?
AOP是Object Oriented Programming(OOP)的补充。
OOP能够很好地解决对象的数据和封装的纵向问题,却不能很好的解决Aspect("方面")分离的横向问题使用价值
认证、事务、日志等等
如:你已经写好一个功能,有一天客户提出一个需求,需要对调用这个服务的用户进行权限认证,这时候通过AspectJ实现一个AOP是你的首选。
AspectJ是怎么干活的?
背景:定义一个Class,如果需要对这个Class的get和set方法进行进行切入
实现方案:
一、定义aj规则文件,通过调用call方法实现around切入
二、定义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;
- }
方案二、定义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();
- }
- }