1.cglib和静态代理和动态代理的区别?
静态代理和动态代理都需要去实现某个接口,然后才能使用,特别是静态代理,一次只能服务一个类,动态代理好一点,可以服务所有的类,但是还是要实现接口,这样有点烦,但是cglib完美的解决了这个问题,可以强行给某个类加入方法,不需要去实现某个接口
2.如何实现
a.需要加方法的类:
package com.lilei.test.proxytest;
/**
* Created by Administrator on 2017/9/26.
*/
public class HelloImp1 {
public void say(String name) {
System.out.println("Hello! "+name);
}
public void eat(String name) {
System.out.println("eat "+name);
}
}
b.cglib代理类
package com.lilei.test.proxytest;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* Created by Administrator on 2017/9/27.
*/
public class CGlibProxy implements MethodInterceptor{
private static CGlibProxy cGlibProxy;
private CGlibProxy(){
}
public static CGlibProxy getInstance(){
if (cGlibProxy == null){
return new CGlibProxy();
}
return cGlibProxy;
}
// private Object target;
//
// public CGlibProxy(Object target) {
// this.target = target;
// }
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
before();
Object result = proxy.invokeSuper(obj,args);
after();
return result;
}
private void before(){
System.out.println("Before");
}
private void after(){
System.out.println("After");
}
/**
* 获取代理
* @param cls
* @param <T>
* @return
*/
public <T> T getProxy(Class<?> cls){
Enhancer en = new Enhancer();//工具类
en.setSuperclass(cls);//设置超类
en.setCallback(this);//设置回调函数
return (T) en.create();
}
}
c .springDemo.xml配置文件,将cglib代理类和想要服务的类关联起来
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/beans/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.lilei.test.AddviceTest"/>
<bean id="transactionManager" class="com.lilei.test.AddviceTest.GreetingThrowAdvice" />
<bean id="greetingIml" class="com.lilei.test.AddviceTest.GreetingImp" />
<bean id ="greetingIntoAdvice" class="com.lilei.test.AddviceTest.GreetingIntroAdvice" />
<bean id="greetingAroundAdvice" class="com.lilei.test.AddviceTest.GreetingImp" />
<!--<aop:aspectj-autoproxy proxy-target-class="true"/>-->
<!--配置一个切面-->
<bean id="greetingAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice" ref="greetingIntoAdvice" /> <!--增强-->
<property name="pattern" value="com.lilei.test.AddviceTest.GreetingIntroAdvice.good.*"/><!--正则表达式-->
</bean>
<!--配置一个代理-->
<bean id="greetingProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!--<property name="interfaces" value="com.lilei.test.AddviceTest.Apology"/>--><!--需要动态实现的接口-->
<property name="target" ref="greetingIml"/><!--目标类-->
<!--<property name="interceptorNames" value="greetingIntoAdvice" />--><!--引入增强-->
<!-- <property name="interceptorNames" value="greetingAdvisor" />-->
<property name="interceptorNames" value="transactionManager" />
<property name="proxyTargetClass" value="true"/>
</bean>
</beans>
d.cglib测试类
package com.lilei.test.proxytest;
/**
* Created by Administrator on 2017/9/28.
*/
public class CGlibProxyTest {
public static void main(String[] args) {
// CGlibProxy cGlibProxy = new CGlibProxy();
// HelloImp1 hello = cGlibProxy.getProxy(HelloImp1.class);
HelloImp1 hello = CGlibProxy.getInstance().getProxy(HelloImp1.class);
hello.say("lieli");
hello.eat("lieli1");
}
}