静态代理、动态代理、springAOP、spring事务

静态代理

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)

    }
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring AOP中,动态代理是实现AOP的一种方式。Spring AOP使用了Java动态代理机制来创建代理对象,并将切面逻辑织入到目标对象的方法调用中。 动态代理是在运行时生成代理对象的一种机制。它不需要在编写代码时就确定要代理的类和方法,而是在运行时根据需要创建代理对象。在Spring AOP中,主要有两种类型的动态代理:基于接口的代理和基于类的代理。 1. 基于接口的代理(JDK动态代理):当目标对象实现了至少一个接口时,Spring AOP会使用JDK动态代理来生成代理对象。JDK动态代理通过实现目标对象所实现的接口来生成代理对象,在调用代理对象的方法时,会通过InvocationHandler接口将方法调用转发给实际的目标对象。 2. 基于类的代理(CGLIB动态代理):当目标对象没有实现任何接口时,Spring AOP会使用CGLIB动态代理来生成代理对象。CGLIB动态代理通过继承目标对象生成一个子类,并覆盖其中的方法来实现代理。调用代理对象的方法时,会先进入子类的方法,然后再调用目标对象的方法。 使用动态代理可以实现对目标对象的拦截和增强,而不需要修改目标对象的源代码。代理对象可以在目标对象的方法执行前、执行后或执行过程中插入额外的逻辑,例如日志记录、性能统计、事务管理等。 需要注意的是,动态代理只能对公共方法进行拦截,对私有方法、静态方法或final方法无法进行拦截。同时,动态代理也只能拦截通过代理对象调用的方法,直接通过目标对象调用方法时无法实现拦截和增强。 总结来说,Spring AOP使用动态代理来实现切面逻辑的织入,可以通过JDK动态代理或CGLIB动态代理来生成代理对象,并将切面逻辑应用到目标对象的方法调用中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值