一、AOP 概念
Joinpoint:它定义在哪里加入你的逻辑功能,对于Spring AOP,Jointpoint指的就是Method。
Advice:特定的Jointpoint处运行的代码,对于Spring AOP 来讲,有Before advice、AfterreturningAdvice、ThrowAdvice、AroundAdvice(MethodInteceptor)等。
Pointcut:一组Joinpoint,就是说一个Advice可能在多个地方织入,
Aspect:这个我一直迷惑,它实际是Advice和Pointcut的组合,但是Spring AOP 中的Advisor也是这样一个东西,但是Spring中为什么叫Advisor而不叫做Aspect。
Weaving:将Aspect加入到程序代码的过程,对于Spring AOP,由ProxyFactory或者ProxyFactoryBean负责织入动作。
Target:这个很容易理解,就是需要Aspect功能的对象。
Introduction:引入,就是向对象中加入新的属性或方法,一般是一个实例一个引用对象。当然如果不引入属性或者引入的属性做了线程安全性处理或者只读属性,则一个Class一个引用也是可以的(自己理解)。Per-class lifecycle or per-instance life cycle
二、AOP 种类
1、静态织入:指在编译时期就织入Aspect代码,AspectJ好像是这样做的。
2、动态织入:在运行时期织入,Spring AOP属于动态织入,动态织入又分静动两种,静则指织入过程只在第一次调用时执行;动则指根据代码动态运行的中间状态来决定如何操作,每次调用Target的时候都执行(性能较差)。
实现静态代理时,代理对象与被代理的对象必须实现同一接口。然后,写很多实现代理的代码,因此业务逻辑被湮没在与业务无关的逻辑这中,所以这种代理没有什么可用性。
package study.spring.lesson04.staticproxy;
public interface ILogin {
boolean login(String username,String password);
}
//纯业务逻辑实现类(被代理的类,目标类)
package study.spring.lesson04.staticproxy;
public class LoginAction implements ILogin{
public boolean login(String username, String password) { //实现的接口
if ("zhangsan".equals(username))
throw new RuntimeException();
else if ("lisi".equals(username) && "1234".equals(password))
return true;
else
return false;
}
}
//实现了附属功能(通知或者称横切功能)代理类
import org.apache.commons.logging.LogFactory;
this.loginobject = loginobject;
}
} else {
}
}
//测试类
import study.spring.lesson04.staticproxy.LoginAction;
import study.spring.lesson04.staticproxy.Loginproxy;
import junit.framework.TestCase;
ILogin login = new Loginproxy(new LoginAction());
login.login("lisi","1234");
}
}
使用动态代理,可以使一个操作对应于多个被代理的对象。操作处理类,必须实现java.lang.reflect.InvocationHandler接口。同时必须定义所要代理的接口。
例子:
//业务逻辑接口,
package study.spring.lesson04.dynamicproxy;
public interface ILogin {
boolean login(String username,String password);
}
//纯业务逻辑实现类,被代理的类
package study.spring.lesson04.dynamicproxy;
public class LoginAction implements ILogin{
public boolean login(String username, String password) {
if ("zhangsan".equals(username))
throw new RuntimeException();
else if ("lisi".equals(username) && "1234".equals(password))
return true;
else
return false;
}
}
//动态代理类的实现(代理类)
package study.spring.lesson04.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class LoginHandler implements InvocationHandler {
private Object targetobject;
private Log log = LogFactory.getLog(LoginHandler.class);
public Object bind(Object targetobject) { //代理对象的产生
this.targetobject = targetobject;
return Proxy.newProxyInstance(targetobject.getClass().getClassLoader(),
targetobject.getClass().getInterfaces(), this); //产生代理对象的方法
}
public Object invoke(Object proxy, Method method, Object[] args) //实现接口
throws Throwable {
if (ILogin.class.isAssignableFrom(targetobject.getClass())) {
if ("login".equals(method.getName())) {
String username = (String)args[0];
log.info("User[" + username + "]is logining");
if ((Boolean) method.invoke(targetobject, args)) { //被代理对象方法的实际调用
log.info("User[" + username + "] login success");
return true;
} else {
log.info("User[" + username + "] login failed");
return false;
}
}
}
return method.invoke(targetobject, args);
}
}
//测试类
package test.study.spring.lesson04;
import study.spring.lesson04.dynamicproxy.LoginHandler;
import study.spring.lesson04.dynamicproxy.ILogin;
import study.spring.lesson04.dynamicproxy.LoginAction;
import junit.framework.TestCase;
public class Testproxy extends TestCase {
public void testDynamicProxy(){
ILogin login =(ILogin) new LoginHandler().bind(new LoginAction());
login.login("lisi", "1234");
}
}