1、Aop
面向切面编程。纵向重复,横向抽取。
2、代理
生活中的实例,找明星拍戏,上综艺…….直接找明星,说明明星太小,如果明星有点名气,那就不用直接访问了,必须先通过访问明星的经纪人,然后由经纪人访问明星。经纪人就是明星的代理。
放在程序中,有一个目标对象,有一个代理对象。你想访问目标对象,必须先通过代理对象,由代理对象决定访问目标对象。Java提供了一个类Proxy能够实现代码。
3、 Spring AOP
利用了代理技术。主要应用于在service层的事务管理。
4、Spring实现AOP的方法:
(1).动态代理
被代理对象必须实现接口,如果没有接口则不能实现动态代理。
(2).cglib代理
第三方代理技术。任何类都可以实现代理,使用继承的机制来实现代理,所以被代理的对象不能被final修饰。
(3).手动实现 动态代理
准备一个UserService和UserServiceImpl
package cn.hd.proxy;
public interface UserService {
void add();
void delete();
void update();
void find();
}
package cn.hd.proxy.impl;
import cn.hd.proxy.UserService;
public class UserServiceImpl implements UserService {
@Override
public void add() {
// System.out.println("开启事务");
System.out.println("添加用户");
// System.out.println("提交用户");
}
@Override
public void delete() {
// System.out.println("开启事务");
System.out.println("删除用户");
// System.out.println("提交事务");
}
@Override
public void update() {
// System.out.println("开启事务");
System.out.println("更新用户");
// System.out.println("提交事务");
}
@Override
public void find() {
// System.out.println("开启事务");
System.out.println("查询用户");
// System.out.println("提交事务");
}
}
准备一个获得UserService代理对象的类
1.获得代理对象通过调用Proxy的newProxyInstance方法。传递三个参数/*getClassLoader()类加载器,getInterfaces()实现类的接口,this:当前对象*/这样的话就得到了一个代理对象。
2.实现代理对象的方法,让这个类 实现InvocationHandler接口 实现他的方法 invoke(被代理的对象,被代理的方法,调用该方法的参数)
3.被代理对象方法还是要被调用,所有调用method.invoke()两个参数,一个是被代理的对象,参数,给类加上一个属性被代理对象,并给该类添加构造函数,在调用被代理对象方法前后,可以加上对应的内容。
package cn.hd.proxy;
import cn.hd.proxy.impl.UserServiceImpl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class UserServiceProxyFactory implements InvocationHandler {
private UserService userService;
publicUserServiceProxyFactory(UserService userService) {
this.userService = userService;
}
public UserServicegetUserServiceProxy(){
/*getClassLoader()类加载器,getInterfaces()实现类的接口,this:当前对象*/
UserService userServiceProxy =(UserService)Proxy.newProxyInstance(UserServiceProxyFactory.class.getClassLoader(),UserServiceImpl.class.getInterfaces(), this);
return userServiceProxy;
}
@Override
/*参数:被代理的对象,被代理的方法,调用该方法的参数*/
public Object invoke(Object proxy,Method method, Object[] args) throws Throwable {
System.out.println("开启事务");
/*调用被代理对象的方法,目标方法*/
Object invoke = method.invoke(userService,args);
System.out.println("提交事务");
return invoke;
}
}
(4).手动实现 cglib代理
准备一个UserService和UserServiceImpl
和上面的一样
准备一个获得UserService代理对象的类
package cn.hd.proxy;
import cn.hd.injection.User;
import cn.hd.proxy.impl.UserServiceImpl;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class UserServiceProxyFactoryCglib implements MethodInterceptor{
public UserServicegetUserServiceProxy(){
/*帮助我们实现代理对象*/
Enhancer enhancer = new Enhancer();
/*设置对谁进行代理*/
enhancer.setSuperclass(UserServiceImpl.class);
/*回调方法*/
enhancer.setCallback(this);
UserService userServiceProxy =(UserService) enhancer.create();
return userServiceProxy;
}
@Override
/*被代理对象,被代理对象方法,参数,代理方法*/
public Object intercept(Object o, Methodmethod, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("开启事务");
Object o1 =methodProxy.invokeSuper(o, objects);
System.out.println("提交事务");
return o1;
}
}
(5).验证
package cn.hd.proxy;
import cn.hd.proxy.impl.UserServiceImpl;
import org.junit.Test;
public class Demo {
@Test
public void fun1(){
/*获得目标对象*/
UserService us = new UserServiceImpl();
/*获得代理对象*/
UserServiceProxyFactory uspf= new UserServiceProxyFactory(us);
UserService userServiceProxy =uspf.getUserServiceProxy();
userServiceProxy.add();
}
@Test
public void fun2(){
UserServiceProxyFactoryCglibuspfc = new UserServiceProxyFactoryCglib();
UserService userServiceProxy =uspfc.getUserServiceProxy();
userServiceProxy.add();
userServiceProxy.delete();
userServiceProxy.find();
userServiceProxy.update();
}
}