主测试类: (BulkBean、FastClass的使用测试代码没保存)
import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** * Created by Administrator on 2014/11/25. */ public class Main { public static void main(String[] args) throws Exception { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"service.xml"}); BeanA obj = (BeanA) ctx.getBean("beanA"); System.out.println(obj); System.out.println(obj.getName()); } public static class MyCallBack implements MethodInterceptor, Callback { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("invoke method : " + method.getName()); return methodProxy.invokeSuper(o, objects); } } public static Method[] getGetMethods(Class clazz) throws Exception { Field[] arr = getFields(clazz); Method[] methods = new Method[arr.length]; for (int i = 0; i < arr.length; ++i) { String methodName = getMethodName("get", arr[i].getName()); Method method = clazz.getMethod(methodName, new Class[]{}); methods[i] = method; } return methods; } public static String[] getGetMethodNames(Class clazz) throws Exception { Field[] arr = getFields(clazz); String[] methods = new String[arr.length]; for (int i = 0; i < arr.length; ++i) { String methodName = getMethodName("get", arr[i].getName()); methods[i] = methodName; } return methods; } public static Method[] getSetMethods(Class clazz) throws Exception { Field[] arr = getFields(clazz); Method[] methods = new Method[arr.length]; for (int i = 0; i < arr.length; ++i) { String methodName = getMethodName("set", arr[i].getName()); Method method = clazz.getMethod(methodName, new Class[]{arr[i].getClass()}); methods[i] = method; } return methods; } public static String[] getSetMethodNames(Class clazz) throws Exception { Field[] arr = getFields(clazz); String[] methods = new String[arr.length]; for (int i = 0; i < arr.length; ++i) { String methodName = getMethodName("set", arr[i].getName()); methods[i] = methodName; } return methods; } public static String getMethodName(String prefix, String varName) { StringBuilder sb = new StringBuilder(); sb.append(prefix); sb.append(varName); sb.setCharAt(prefix.length(), Character.toUpperCase(varName.charAt(0))); return sb.toString(); } public static Class[] getFieldTypes(Class clazz) { Field[] arr = getFields(clazz); Class[] result = new Class[arr.length]; for (int i = 0; i < arr.length; ++i) { result[i] = arr[i].getType(); } return result; } public static Field[] getFields(Class clazz) { List<Field> fields = new ArrayList<Field>(10); while (!clazz.equals(Object.class)) { Field[] arr = clazz.getDeclaredFields(); Collections.addAll(fields, arr); clazz = clazz.getSuperclass(); } Field[] result = new Field[fields.size()]; for (int i = 0; i < fields.size(); ++i) { result[i] = fields.get(i); } return result; } }
BeanFactory后处理器:
package cglib; import net.sf.cglib.proxy.Enhancer; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import net.sf.cglib.proxy.Callback; import java.lang.reflect.Method; /** * Created by Administrator on 2014/11/25. */ public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { String[]arr=configurableListableBeanFactory.getBeanDefinitionNames(); for(String s:arr){ BeanDefinition definition =configurableListableBeanFactory.getBeanDefinition(s); String name=definition.getBeanClassName(); try { Class clazz=Class.forName(name); Enhancer enhancer=new Enhancer(); enhancer.setSuperclass(clazz); enhancer.setCallbackType(MyCallBack.class); definition.setBeanClassName(enhancer.createClass().getName()); } catch (ClassNotFoundException e) { e.printStackTrace(); } } configurableListableBeanFactory.addBeanPostProcessor(new BeanPostProcessor() { @Override public Object postProcessBeforeInitialization(Object o, String s) throws BeansException { return o; } @Override public Object postProcessAfterInitialization(Object o, String s) throws BeansException { Class clazz=o.getClass(); try { Method m=clazz.getDeclaredMethod("setCallbacks",new Class[]{Callback[].class}); m.invoke(o,new Object[]{new Callback[]{new MyCallBack()}}); } catch (Exception e) { e.printStackTrace(); } return o; } }); } }
方法AOP逻辑:
package cglib; import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /** * Created by Administrator on 2014/11/25. */ public class MyCallBack implements MethodInterceptor,Callback { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("invoke method : "+method.getName()); return methodProxy.invokeSuper(o,objects); } }
BeanA类文件:
/** * Created by Administrator on 2014/11/25. */ public class BeanA { private String name; private Long id; public String getName() { return name; } public void setName(String name) { this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } }
Spring Bean 配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName"> <bean id="tt" name="beanA" class="BeanA"> <property name="name" value="myname"/> </bean> <bean id="myBeanFactoryPostProcessor" class="cglib.MyBeanFactoryPostProcessor"></bean> </beans>
POM文件:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cglib-zxl</groupId> <artifactId>study</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>cglib</groupId> <artifactId>cglib-nodep</artifactId> <version>2.1_3</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.0.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.0.3.RELEASE</version> </dependency> </dependencies> </project>