AOP理解:就是把 业务代码和关注点代码分离开来,关注点就是(重复的代码、方法)
切面就是 关注点形成的类
例如,当用户直接访问目标对象进行数据库操作,当发生错误返回一场。这样显然是不合理的,这时候中间就需要代理对象。
就好比商家 需要商演,你想找某个明星出演活动,你不可能直接去找明星谈合作,你可以通过经纪人来谈合作;
第一种静态代理
package com.staticpackage;
public interface IUserDao {
public void save() throws Exception;
}
package com.staticpackage;
/**
* 目标对象
* @author 11947
*
*/
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("数据已经保存");
}
}
静态代理
package com.staticpackage;
/**
* 代理对象(静态代理)
* @author 11947
*
*/
public class UserDaoProxy implements IUserDao {
private IUserDao target;
public UserDaoProxy(IUserDao target) {
this.target=target;
}
@Override
public void save() throws Exception {
// TODO Auto-generated method stub
System.out.println("开启事务");
target.save();
System.out.println("提交事务");
}
}
测试类
package com.staticpackage;
public class Test {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
IUserDao target = new UserDao();
UserDaoProxy proxy = new UserDaoProxy(target);
proxy.save();
}
}
静态代理的缺点::因为代理对象需要实现与目标对象相同的接口,会有很多代理,类接口增加方法,目标对象与代理对象都需要维护。为了解决这一点,就需要jdk动态代理
第二种动态代理(jdk代理)
package com.dynamic;
public interface IUserDao {
public void save() throws Exception;
}
package com.dynamic;
/**
* 目标对象
* @author 11947
*
*/
public class UserDao implements IUserDao{
@Override
public void save() {
System.out.println("数据已经保存");
}
}
package com.dynamic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyFactory {
//目标对象
private Object target;
public ProxyFactory(Object target) {
this.target= target;
}
//生成代理对象
public Object getProxyInstance() {
return Proxy.newProxyInstance(//jdk中的方法目标对象必须有实现接口,否则不能使用动态代理
target.getClass().getClassLoader(),//获取目标对象类加载器
target.getClass().getInterfaces(),//目标对象实现的接口类型
new InvocationHandler() { //事件处理器
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
System.out.println("开启事务");
Object result=method.invoke(target, args);
System.out.println("提交事务");
return result;
}
});
}
}
package com.dynamic;
/**
*
* 目标
*
* @author 11947
*
*/
public class Test {
public static void main(String[] args) throws Exception {
IUserDao target=new UserDao();
IUserDao proxy=(IUserDao) new ProxyFactory(target).getProxyInstance();
proxy.save();
}
}
第三种cglib代理
package com.cglib;
/**
* 目标对象
* @author 11947
*
*/
public class UserDao{
public void save() {
System.out.println("数据已经保存");
}
}
package com.cglib;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
/**
* cglib子类工厂(对UserDao在内存中动态创建一个代理)
* @author 11947
*
*/
public class ProxyFactory implements MethodInterceptor {
//目标对象
private Object target;
public ProxyFactory(Object target) {
this.target=target;
}
public Object getProxyInstance() {
//1.工具类
Enhancer en=new Enhancer();
//2.设置父类
en.setSuperclass(target.getClass());
//3.设置回调函数
en.setCallback(this);
//4.创建代理对象
return en.create();
}
@Override
public Object intercept(Object arg0, Method method, Object[] arg2, MethodProxy arg3) throws Throwable {
//执行目标对象的方法
System.out.println("开启事务");
Object resultValue=method.invoke(target, arg2);
System.out.println("提交事务");
return resultValue;
}
}
package com.cglib;
/**
*
* cglib代理 子类代理,在内存中构建一个子类对象从未实现对目标对象的扩展
*
* 在内存中动态创建对象的子类
* 目标对象不可以是final
* 目标对象方法是final、staic,则不会拦截
*
*
* @author 11947
*
*/
public class Test {
public static void main(String[] args) throws Exception {
//目标对象
UserDao target=new UserDao();
//代理对象
UserDao proxy=(UserDao) new ProxyFactory(target).getProxyInstance();
proxy.save();
System.out.println(proxy.getClass());
}
}
cglib代理不需要有接口,它是在内存中创建一个子类对象,从而对目标对象的扩展