OOP是关注将需求功能划分为不同的并且相对独立,封装良好的类,并让它们有着属于自己的行为,依靠继承和多态等来定义彼此的关系;AOP是希望能够将通用需求功能从不相关的类当中分离出来,能够使得很多类共享一个行为,一旦发生变化,不必修改很多类,而只需要修改这个行为即可。
AOP是使用切面(aspect)将横切关注点模块化,OOP是使用类将状态和行为模块化。在OOP的世界中,程序都是通过类和接口组织的,使用它们实现程序的核心业务逻辑是十分合适。但是对于实现横切关注点(跨越应用程序多个模块的功能需求)则十分吃力,比如日志记录,验证。
以上来自转载。我觉得简单明了。
下面就着重介绍下两种动态代理机制。
1、JDK动态代理。
invoke方法里,比如判断权限的代码。
首先我们创建一个目标类,也就是我们的业务代码,我们想要给他创建代理类。
目标类代码如下:
package aopdaili;
public class UserServiceImpl implements UserService{
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public void saveUser() {
System.out.println("保存用户");
}
public void updateUser() {
System.out.println("修改用户");
}
}
里边我们有一个参数User类,和我们的业务逻辑代码,save User(),和updateUser()。
我们将在测试类里访问我们目标类里的业务代码,但是必须经过代理类里的权限判断。
代理类代码如下:jdkProxy.java
package aopdaili;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//JDK代理类是继承InvocationHandler这个接口的
public class jdkProxy implements InvocationHandler {
private Object targetObj;
public Object getTargetObj() {
return targetObj;
}
public void setTargetObj(Object targetObj) {
this.targetObj = targetObj;
}
//返回语句中:第一个参数是目标类的类加载器,第二个参数是目标类的接口,
//第三个参数:设置回调对象,当前代理对象的方法被调用时,会委派该参数去调用invoke代理类负责切面:有没有权限都是在代理类里控制的。
public Object createjdkProxy(Object target) {
this.targetObj = target;
return Proxy.newProxyInstance(this.targetObj.getClass().getClassLoader(),
this.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] arg2) throws Throwable {
// TODO Auto-generated method stub
//获得目标对象的get方法
Method getmethod = this.targetObj.getClass().getMethod("getUser", null);
//通过反射获得调用方法的方法值
Object user = getmethod.invoke(this.targetObj, null);
Object obj = null;
if(user!=null) {
//通过调用目标对象的
obj = method.invoke(this.targetObj, null);
}else {
System.out.println("您还没有登录!");
}
return obj;
}
}
@Test
public void test01() {
UserServiceImpl userserviceimle = new UserServiceImpl();
userserviceimle.setUser(null);
//通过业务接口来接受代理对象
UserService userservice = (UserService)new jdkProxy().createjdkProxy(userserviceimle);
System.out.println(userservice.getClass());
userservice.saveUser();
}
代码具体解释都在注释标注;需要注意的就是必须继承InvocationHandler接口,将您要添加的动态代码放在Invoke方法里
测试类:
@Test
public void test01() {
UserServiceImpl userserviceimle = new UserServiceImpl();
userserviceimle.setUser(null);
//通过业务接口来接受代理对象
UserService userservice = (UserService)new jdkProxy().createjdkProxy(userserviceimle);
System.out.println(userservice.getClass());
userservice.saveUser();
}
他和JDK动态代理的区别就是他是继承MethodInterceptor接口。将你想增加的代码添加到intercept方法里。
他的代理类代码如下:
package aopdaili;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
public class cglibProxy implements MethodInterceptor {
private Object targetObj;
public Object createProxyInstance( Object targetObj) {
this.targetObj = targetObj;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.targetObj.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object arg0, Method method, Object[] arg2, MethodProxy arg3) throws Throwable {
// TODO Auto-generated method stub
//获得目标对象的get方法
Method getmethod = this.targetObj.getClass().getMethod("getUser", null);
//通过反射获得调用方法的方法值
Object user = getmethod.invoke(this.targetObj, null);
Object obj = null;
if(user!=null) {
//通过调用目标对象的
obj = method.invoke(this.targetObj, arg2);
}else {
System.out.println("您还没有登录!");
}
return obj;
}
}
其他代码一样。