静态代理
public interface UserService {
public void register(User user);
public boolean login(String name,String password);
}
public class UserServiceImpl implements UserService{
@Override
public void register(User user) {
System.out.println("userServiceImpl.register....");
}
@Override
public boolean login(String name, String password) {
System.out.println("userServiceImpl.login....");
return false;
}
}
public class UserServiceStaticProxy implements UserService{
private UserServiceImpl userService = new UserServiceImpl();
@Override
public void register(User user) {
System.out.println("----增强方法---");
userService.register(user);
}
@Override
public boolean login(String name, String password) {
System.out.println("---增强方法---");
userService.login(name,password);
return false;
}
}
public class TestProx {
@Test
public void test(){
UserService userService = new UserServiceStaticProxy();
userService.login("aa","123");
}
}
缺点 :每一个类都需要一个代理类,导致类特别多 增强方法如果需要改变每个代理类都需要改变
动态代理 (这里所说的动态代理是spring提供的动态代理类,底层依旧是jdk、cglib动态代理)
userService类 和UserServiceImpl 类 同上静态代理 额外添加一个Before类继承MethodBeforeAdvice 并且加入spring容器
import java.lang.reflect.Method;
public class Before implements MethodBeforeAdvice {
@Override
/**
* 把加强的额外功能写在before方法中
*/
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("----增强方法---");
}
}
或则是MethodInterceptor 实现类
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MyMotherInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable { //invocation 封装了jdk动态代理的这几个参数 Object proxy, Method method, Object[] args
System.out.println("befor-------原始方法前后可以执行自己逻辑---------");
Object object = invocation.proceed(); //代表原始方法运行,可以是login(),也可以是regist()
System.out.println("after-------原始方法前后可以执行自己逻辑---------");
return object;
}
}
application.xml 中添加
<bean id="userService" class="com.proxy.UserserviceImpl">
<bean id="before" class="com.proxy.Before">
<bean id="myMotherInterceptor" class="com.proxy.MyMotherInterceptor">
<aop:config>
<!-- 切入点表达式 -->
<aop:pointcut id="pc" expression="execution(**(..))">
<!-- 组装:把切入点和额外功能整合 -->
<aop:advisor advice-ref="before" pointcut-ref="pc">
<!-- <aop:advisor advice-ref="myMotherInterceptor" pointcut-ref="pc"> -->
</aop:config>
此时从spring容器中获取的UserserviceImpl 变为动态代理类
MethodBeforeAdvice、MethodInterceptor 整个过程大致就是使用的jdk提供的动态代理的接口InvocationHandler(提供额外方法)和Proxy
我的理解Aop 是通过一系列的注解或则标签,拿到对应的类的方法,然后通过spring提供的MethodBeforeAdvice或则MethodInterceptor动态代理添加额外方法,即aop的切入方法 (不一定对,自己猜测)
写一个JDK 动态代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class JDKProxyDemo {
public static void main(String[] args) {
UserService userService =new UserServiceImpl();
// InvocationHandler handler = new InvocationHandler() {
// @Override
// public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// return null;
// }
// };
InvocationHandler handler = (proxy,method,arg)->{
System.out.println("befor-------原始方法前后可以执行自己逻辑---------");
Object ret = method.invoke(userService,arg); //执行原始方法
System.out.println("after-------原始方法前后可以执行自己逻辑---------");
return ret;
};
UserService userService1Proxy =(UserService) Proxy.newProxyInstance(JDKProxyDemo.class.getClassLoader(),userService.getClass().getInterfaces(),handler );
userService1Proxy.login("aaa","123");
}
}
Aop的底层实现
/**
*此伪代码
*/
public class MyBeanPostProessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { //bean 就是被代理类userService
UserServiceProxy = Proxy.newProxyInstance(classloader,interface,invocationHandler)
return UserServiceProxy; 返回的也是代理对象,所以aop 代理类通过bean id获取的是代理对象
}
}
/**
*实现代码
*/
class MyBeanPostProessor implements BeanPostProcessor {
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
//bean 就是被代理类userService
InvocationHandler handler =(proxy,method,args)->{
System.out.println("------加强方法------");
Object object = method.invoke(bean,args);
return object;
};
return Proxy.newProxyInstance(MyBeanPostProessor.class.getClassLoader(),bean.getClass().getInterfaces(),handler)
}
}