学的有点懵,有些理解还有些问题想问老师
在Bean的声明周期的第五步和第八步方法中,因为所有bean在初始化的前后都会 调用这个接口的对应的方法,所以它们的参数1为当前初始化的Bean对象,也就是 我们在xml配置的UserDaoImpl这个类对象。 参数2是配置类对象中的id的值,是这样嘛? <bean id="userDao" class="com.zhou.ioc.demo3.UserDaoImpl"/>
Proxy.newProxyInstance():对某个类产生代理类,返回Object类型的代理类对象实例 Proxy.newProxyInstance()需要三个参数: 参数1:需要代理的类的加载器 参数2:动态代理类需要实现的接口,也就是配置文件<bean>标签id为userDao对应的实现类UserDaoImpl 它所需要实现接口:UserDao <bean id="userDao" class="com.zhou.ioc.demo3.UserDaoImpl"/> 参数3:表示帮组动态代理的方法 InvocationHandler(),这里我们使用内部类的方式去创建这个方法。 我们在这个内部类里面重写了InvocationHandler()方法的invoke。该invoke方法中需要三个参数: 参数一:proxy是InvocationHandler中的invoke方法的参数名(从同学提问老师回答中看到的) 疑问:这proxy本身不就是在inovke方法中的参数嘛?我也知道这是invoke方法中的三个参数中 的其中一个Object类型的参数名,那他具体表示什么? 参数二:这里的method属性传入的是Method类的对象,这个method对象是用真正的方法名,由方法名 和形参抽象出Method对象。(从同学提问老师回答中看到的) 疑问:因为前面进行了userDao.equlse的判断,我们可以得到在xml中配置id为userDao的这个类, 但是这个类中有这么多方法,这个Method表示的是哪个方法抽象出来的Method对象?而且这里 老师是不是说错了,它说的是这里的method属性传入的是Method类的对象,这里不应该是 “method属性传入的是Method方法的对象”嘛? 参数三:args[]中传入的是原方法执行所需要的参数,由于参数可能有多个,所以使用数组(从同学提问老师 回答中看到的) 疑问:这里我有点懵,原方法指的是哪个方法?id为userDao对应的类中有那么多方法。而且这里 又没进行筛选条件判断,这里指的是哪个方法? 在该方法中,我们针对性的对某个方法进行增强,最后返回 return method.invoke(bean,args); 这里我也不太理解,method是哪个方法对象?inovke方法是什么方法?代理方法嘛?它所需要的这两个 参数是什么? 执行完这句话之后返回一个Oject类型的值,然后赋值给Oject proxy,也就是最终返回打代理对象。
正在回答
同学你好,1、代理类是对对应的类产生的实例对象的代理,例如:
2、如下所示,对条件成立的内容执行代理。
在invoke方法中执行对应方法的增强。
如果我的回答解决了你的疑惑,请采纳,祝学习愉快~
老师,我刚刚看了一下动态代理,你看一下我结合这个案例的理解有没有错: Proxy类是个调度器,它提供用于创建动态代理的静态方法类和实例, 由这些方法创建的动态代理类,它也是所有类的超类.它有提供一个 newProxyInstance静态方法,这个返回指定接口的代理类的实例将方法 调用分派到指定的调用处理程序。用来创建动态代理的class和实例. newProxyInstance这个创建代理类的方法需要三个参数: 参数1:类加载器 参数2:动态代理类需要实现的接口(案例中实现类是UserDaoImpl,它的接口是userDao,是 这样嘛? 参数3: InvocationHandler接口是一个遵循单一职责原则的增强器,这个增强器 里面只有一个invoke接口方法我们就是在这个方法中进行业务增强的: public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; 我们在案例中是使用匿名内部类来实现它的。 这个invoke方法有三个参数: 参数1:代理对象 参数2:我们要去优化,要去拦截的方法 参数3:这个方法需要的参数 我们案例中就是在这里对save这个方法进行增强的,因为是动态代理,我们无法 用直接调用对象的方法来执行该方法,所以这里我们利用反射的原理来执行: method.invoke(bean,args); 并且将该方法的返回值返回,如果不是该方法,就不 进行增强,直接执行该方法,然后返回。 一般我们可以在这个反射方法执行前和执行后进行处理,达到增强的效果 Proxy.newProxyInstance的三个参数我们都有了,我们将 执行这个Proxy.newProxyInstance 这个静态方法,最后会根据我们配置文件中是否有id为userDao这个类对象进行Bean对象的返回, 如果有则返回代理后的bean对象,如果没有则返回原有bean对象 Proxy只管创建动态代理的实例,这个实例具体干什么事情是由这个 InvocationHandler来做的,它们的分工非常明确,一个只管生成员工, 一个负责定制员工工作执行的流程和标准。
@Override public Object postProcessAfterInitialization(final Object bean, String benName) throws BeansException { System.out.println("第八步:初始化后方法...."); //判断是否对应的类,userDao为配置文件中类对象的id if("userDao".equals(benName)){ //Proxy.newProxyInstance():对某个类产生代理类,返回Object类型的代理类对象 Object proxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //针对某个方法进行增强 if("save".equals(method.getName())){ //调用方法前的增强,一般不会是输出,这里只是测试 System.out.println("权限校验====前置增强"); //通过反射执行我们需要代理的方法 Object obj = method.invoke(bean,args); //调用方法后的增强 System.out.println("增强完毕====后置增强"); return obj; } //如果是其他方法就直接执行该方法 return method.invoke(bean,args); } }); return proxy; }else { return bean; } }
这里我增强这里我稍微修改了一下,还有一个问题就是newProxyInstance的第二个参数表示: 动态代理类需要实现的接口(案例中实现类是UserDaoImpl,它的接口是userDao,是这样嘛? 麻烦老师看一下我的理解有没有问题
同学你好,1、同学的说法是正确的。Object bean, String beanName是 applicationContext.getBean获取对应到对应的对象和对象名。
2、疑问:proxy本身不就是在inovke方法中的参数嘛?我也知道这是invoke方法中的三个参数中的其中一个Object类型的参数名,那他具体表示什么.
其实这里的proxy参数传递的即是代理类的实例。
3、疑问:这个Method表示的是哪个方法抽象出来的Method对象。
这里的method就是需要调用的方法的代理对象,即需要执行的方法;所以这里传递的参数就是需要执行的方法。
4、原方法指的是哪个方法,原方法其实就是未代理前的方法。
疑问:又没进行筛选条件判断,这里指的是哪个方法
如上所示,进行了条件筛选。所以还麻烦同学具体描述一下-->没进行筛选条件判断。
5、method是哪个方法对象-->传递的就是需要调用的方法。
invoke方法:
invoke()方法是Method类的一个方法,在执行save()、update()、delete()等方法时,会去调用invoke()方法,执行invoke()方法中的内容。
这里的Method就是Method类型的参数,Method是java.lang.reflect下的一个类。
method.invoke的意思其实就是执行方法的意思。
如果老师没有理解正确同学想表达的意思,还麻烦同学具体描述一下。
如果我的回答解决了你的疑惑,请采纳,祝学习愉快~
- 参与学习 人
- 提交作业 323 份
- 解答问题 8263 个
本阶段将带你学习主流框架SSM,以及SpringBoot ,打通成为Java工程师的最后一公里!
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星