1. spring的BeanNameAutoProxyCreator自动创建事务代理的小问题
事务一般是指数据库事务吧。当然不是一个方法一个事物,有的方法也许根本不需要事务。
2. springcloud 如何创建自己的动态代理
最近需要需要统计每一个节点memcache的命中、并发、超时情况。
memcache client选择的xmemcached
<dependency>
<groupId>com.googlecode.xmemcached</groupId>
<artifactId>xmemcached</artifactId>
<version>2.0.0</version></dependency>
3. spring的动态代理有几种实现方式
JAVA 代理实现
代理的实现分动态代理和静态代理,静态代理的实现是对已经生成了的JAVA类进行封装。
动态代理则是在运行时生成了相关代理累,在JAVA中生成动态代理一般有两种方式。
JDK自带实现方法
JDK实现代理生成,是用类 java.lang.reflect.Proxy, 实现方式如下
EX:
publicclassJDKProxy{
(finalObjectc){
returnProxy.newProxyInstance(c.getClass().getClassLoader(),c.getClass().getInterfaces(),//JDK实现动态代理,但JDK实现必须需要接口
newInvocationHandler(){
publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{
//TODOAuto-generatedmethodstub
ObjectreObj=null;
System.out.print("yousay:");
reObj=method.invoke(c,args);
System.out.println("["+Calendar.getInstance().get(Calendar.HOUR)+":"
+Calendar.getInstance().get(Calendar.MINUTE)+""
+Calendar.getInstance().get(Calendar.SECOND)+"]");
returnreObj;
}
});
}
}
测试代理类方法
publicclassTestForPoxy{
publicstaticvoidmain(String[]args){
ServiceTestservice=newServiceTestImpl();
System.out.println(service.getClass().getSimpleName());
ServiceTestpoxyService=(ServiceTest)JDKProxy.getPoxyObject(service);
System.out.println(poxyService.getClass().getSuperclass());
poxyService.saySomething("hello,MyQQcodeis107966750.");
poxyService.saySomething("what'syourname?");
poxyService.saySomething("onlyfortest,hehe.");
}
}
1, Proxy实现代理的目标类必须有实现接口
2, 生成出来的代理类为接口实现类,和目标类不能进行转换,只能转为接口实现类进行调用
明显特点:通过此方法生成出来的类名叫做 $Proxy0
用CGLIB包实现
CGLIB是一个开源项目,官方网址是:http://cglib.sourceforge.net/,可以去上面下载最新JAR包,
本项目用的是cglib-3.0.jar
本项目还加入了依赖JAR包asm-4.0.jar,asm-util-4.0.jar
实现方式如下
EX:
publicclassCGLIBProxy{
(Objectc){
Enhancerenhancer=newEnhancer();
enhancer.setSuperclass(c.getClass());
enhancer.setCallback(newMethodInterceptor(){
publicObjectintercept(Objectarg0,Methodarg1,Object[]arg2,MethodProxyproxy)throwsThrowable{
System.out.print("yousay:");
proxy.invokeSuper(arg0,arg2);
System.out.println("["+Calendar.getInstance().get(Calendar.HOUR)+":"
+Calendar.getInstance().get(Calendar.MINUTE)+""+Calendar.getInstance().get(Calendar.SECOND)
+"]");
returnnull;
}
});
returnenhancer.create();
}
}
测试代理类方法
publicclassTestForPoxy{
publicstaticvoidmain(String[]args){
ServiceTestservice=newServiceTestImpl();
System.out.println(service.getClass().getSimpleName());
//ServiceTestpoxyService=(ServiceTest)JDKProxy.getPoxyObject(service);
ServiceTestpoxyService=(ServiceTest)CGLIBProxy.getPoxyObject(service);
System.out.println(poxyService.getClass().getSuperclass());
poxyService.saySomething("hello,MyQQcodeis107966750.");
poxyService.saySomething("what'syourname?");
poxyService.saySomething("onlyfortest,hehe.");
}
}
1, CGLIB实现方式是对代理的目标类进行继承
2, 生成出了的代理类可以没方法,生成出来的类可以直接转换成目标类或目标类实现接口的实现类,因JAVA向上转换
明显特点:通过输出看出,看出生成出的代理类的parent类为代理的目标类
4. Spring框架的动态代理是干什么用的
spring的动态代理实现有两种,一种第三方,一种是JDK的反射。
动态代理可以快速地实现工厂生成对象实例注入业务中使用到的实例。
5. spring 得不到动态代理类
把你的动态代理配置贴出来。
spring使用CGLIB强制代理,需要在配置文件头部声明
<!--声明使用CGLIB自动创建代理Bean-->
<aop:aspectj-autoproxyproxy-target-class="true"/>
如果需要对业务层添加事物拦截还需要进行如下配置
<!--定义事务管理拦截器-->
<beanid="transactionInterceptor"
class="添加事物拦截处理类">
<!--注入DAL客户端接口-->
<propertyname="添加数据源id"ref="dalClient"/>
</bean>
<!--定义bean自动代理容器-->
<beanclass="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<propertyname="interceptorNames">
<list>
<!--配置拦截器-->
<value>transactionInterceptor</value>
</list>
</property>
<propertyname="beanNames">
<list>
<!--需要拦截serivce的beanName,支持通配-->
<value>*Service</value>
</list>
</property>
<propertyname="proxyTargetClass"value="true"/>
<propertyname="exposeProxy"value="true"/>
</bean>
6. 使用spring的动态代理功能时为什么必须指定
拦截某些类的话,会判断这个类是否实现了接口,如果实现了接口就会用jdk 动态代理来创建代理对象;如果没有这个类没有实现接口情况下,则用CGLIB来创建代理对象。
JDK动态代理:
public class JDKProxy implements InvocationHandler {
private Object targetObject;//代理的目标对象
public Object createProxyInstance(Object targetObject){
this.targetObject = targetObject;
/*
* 第一个参数设置代码使用的类装载器,一般采用跟目标类相同的类装载器
* 第二个参数设置代理类实现的接口
* 第三个参数设置回调对象,当代理对象的方法被调用时,会委派给该参数指定对象的invoke方法
*/
return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(),
this.targetObject.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return method.invoke(this.targetObject, args);//把方法调用委派给目标对象
}
}
当目标类实现了接口,我们可以使用jdk的Proxy来生成代理对象。
使用CGLIB生成代理:
public class CGLIBProxy implements MethodInterceptor {
private Object targetObject;//代理的目标对象
public Object createProxyInstance(Object targetObject){
this.targetObject = targetObject;
Enhancer enhancer = new Enhancer();//该类用于生成代理对象
enhancer.setSuperclass(this.targetObject.getClass());//设置父类
enhancer.setCallback(this);//设置回调用对象为本身
return enhancer.create();
}
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
return methodProxy.invoke(this.targetObject, args);
}
}
CGLIB可以生成目标类的子类,并重写父类非final修饰符的方法。
7. 关于spring aop的自动代理的问题
在配置文件中加入
<bean id="logBeforeAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<!--这个local是指作为拦截器的那个bean 。 根据你的需求写-->
<ref local="logBefore"/>
</property>
<!-- 指定Controller类中的所有方法 -->
<property name="patterns">
<value>.*.*</value>
</property>
</bean>
8. spring中aop的动态代理机制有哪些
1.事务管理: (1)数据库事务:(2)编程事务(3)声明事物:Spring AOP-->声明事物
2.日志处理:
3.安全验证: Spring AOP---OOP升级
静态代理原理:目标对象:调用业务逻辑 代理对象:日志管理
表示层调用--->代理对象(日志管理)-->调用目标对象
动态代理原理:spring AOP采用动态代理来实现
(1)实现InvocationHandler接口
(2)创建代理类(通过java API)
9. 请问怎样配置Spring的事务自动代理啊我配置的这个怎么出现异常
<ref bean="transactionManger" /> 掉了一个a
transactionManager"
而且里面也没有声明 transactionMangaer bean
其实这个配置很麻烦
为什么不用Spring 2.0 的声明式AOP
CGLIB代理在运行期间产生目标对象的子类,该子类通过装饰器设计模式加入到Advice中。因为CGLIB代理是目标对象的子类,则必须考虑保证如下两点:
目标类不能声明成final,因为final类不能被继承,无法生成代理。
目标方法也不能声明成final,final方法不能被重写,无法得到处理。