CGLIB(Enhancer/FastClass/BulkBean) & spring容器初始化过程

主测试类: (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>


你可能感兴趣的:(spring,callback,Enhancer,FastClass,BulkBean)