AOP编程是面向切面编程,说白了,一段代码的执行归根结底是方法的执行,当一个系统写好之后,往往需要新的功能或者添加一些新的操作,这些新的功能又是一些方法,这些方法需要嵌入到原来的系统中,让
他们在系统原有方法的执行前或者后等等位置执行,这个时候,有两种方案,修改原来的代码,违背了OCP,方案二,使用AOP;
AOP编程就是在程序的执行过程中找到一些
切入点,嵌入一些新的方法,以改变程序原来的执行过程,宏观上看,程序的功能变强大了。
Java语言中AOP是用JDK动态代理技术来实现的:代码
class="java" name="code">
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface IUserBean {
public void getUser();
public void addUser();
public void updateUser();
public void deleteUser();
}
class UserBean implements IUserBean {
private String username = null;
public UserBean() {
}
public UserBean(String username) {
this.username = username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUsername()
{
return this.username;
}
public void addUser() {
System.out.println("this is addUser() method!");
}
public void deleteUser() {
System.out.println("this is deleteUser() method!");
}
public void getUser() {
System.out.println("this is getUser() method!");
}
public void updateUser() {
System.out.println("this is updateUser() method!");
}
}
[color=red]class JDKProxy implements InvocationHandler {
private Object targetObject;
public Object createProxyObject(Object targetObject)
{
this.targetObject=targetObject;
return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(),this.targetObject.getClass().getInterfaces(),this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
UserBean userBean = (UserBean) targetObject;
String userName = userBean.getUsername();
//权限判断
if(userName!=null && !"".equals(userName)) {
//调用目标对象的方法
return method.invoke(targetObject, args);
}
else return null;
}
}[/color]
public class Demo{
public static void main(String[] args) {
JDKProxy jProxy = new JDKProxy();
// IUserBean userBean = (IUserBean) jProxy.createProxyObject(new UserBean(""));
IUserBean userBean = (IUserBean) jProxy.createProxyObject(new UserBean("aaa"));
userBean.addUser();
userBean.updateUser();
userBean.deleteUser();
userBean.getUser();
}
}
可以看到,JDK动态
代理模式其实就是使用了代理模式,创建了一个代理对象。
这个代理对象将原来的方法周围及嵌入了一些新方法,其余代理模式唯一的区别是,代理模式直接覆盖
接口的方法,而jdk动态代理中使用了反射技术,仅仅需要覆盖InvokerHandler接口的invoke方法。
但是JDK动态代理仅仅对实现接口的那些类支持AOP编程,对于不实现接口的那些类则无能为力。为了解决这个问题我们使用CGLIG的代理技术,
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
class UserBean {
private String username = null;
public UserBean() {
}
public UserBean(String username) {
this.username = username;
}
public void setUsername(String username) {
this.username = username;
}
public String getUsername()
{
return this.username;
}
public void addUser() {
System.out.println("this is addUser() method!");
}
public void deleteUser() {
System.out.println("this is deleteUser() method!");
}
public void getUser() {
System.out.println("this is getUser() method!");
}
public void updateUser() {
System.out.println("this is updateUser() method!");
}
}
class CGLibProxy implements MethodInterceptor {
private Object targetObject;
public Object createProxyObject(Object targetObject) {
this.targetObject = targetObject;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.targetObject.getClass()); //非final 进行覆盖
enhancer.setCallback(this); //回调,通过
return enhancer.create(); //创建代理对象
}
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
UserBean userBean = (UserBean) targetObject;
String userName = userBean.getUsername();
Object result = null;
if(userName!=null && !"".equals(userName)) {
//调用目标对象的方法
return methodProxy.invoke(targetObject, args);
}
else return null;
}
}
public class Demo{
public static void main(String[] args) {
CGLibProxy cProxy = new CGLibProxy();
// UserBean userBean = (UserBean) jProxy.createProxyObject(new UserBean(""));
UserBean userBean = (UserBean) cProxy.createProxyObject(new UserBean("aaa"));
userBean.addUser();
userBean.updateUser();
userBean.deleteUser();
userBean.getUser();
}
}
Spring的AOP技术就是基于这两个技术实现的。