把Spring容器中的bean绑定到通过代码创建的对象

Spring提供了对配置中创建对象的字段实例注入。但如果是通过代码创建或者动态创建的对象,由于不受Spring管理,因此没有机会执行字段实例的注入。Google了一把,没发现可以用的方法。因此只能写了一小段代码。对于这种情况,可以通过反射的方式找到对象的字段和方法定义,并注入之。以下为具体实现。Registry类保存了Spring生成的context,在需要的时候随时可以调用。
public final class Registry
{
    private Registry() {}

    private static ApplicationContext context;

    public static void setApplicationContext(ApplicationContext context)
    {
        Registry.context = context;
    }

    public static <T> T getBean(String configName, Class<T> cls)
    {
        return getBean(configName, cls, null);
    }

    public static <T> T getBean(String configName, Class<T> cls, T defaultValue)
    {
        assert (context != null);
        T value = context.getBean(configName, cls);
        return (value != null) ? value : defaultValue;
    }

    public static void wire(Object o)
    {
        wire(o, o.getClass());
    }

    private static void wire(Object o, Class<?> cls)
    {
        Field[] fields = cls.getDeclaredFields();
        for (Field field : fields) {
            Autowired autowired = field.getAnnotation(Autowired.class);
            if (autowired != null) {
                Class<?> fieldClass = field.getDeclaringClass();
                Object bean = context.getBean(fieldClass);
                if (bean != null) {
                    field.setAccessible(true);
                    try {
                        field.set(o, bean);
                    } catch (IllegalArgumentException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
        Method[] methods = cls.getDeclaredMethods();
        for (Method method : methods) {
            Autowired autowired = method.getAnnotation(Autowired.class);
            if (autowired != null) {
                Class<?>[] paramTypes = method.getParameterTypes();
                if (paramTypes.length == 1) {
                    Object bean = context.getBean(paramTypes[0]);
                    if (bean != null) {
                        method.setAccessible(true);
                        try {
                            method.invoke(o, bean);
                        } catch (IllegalArgumentException e) {
                            e.printStackTrace();
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        } catch (InvocationTargetException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        Class<?> superCls = cls.getSuperclass();
        if (!superCls.equals(Object.class)) {
            wire(o, superCls);
        }

    }

    public static void stopContext()
    {
        assert (context != null);
        ((Lifecycle) context).stop();
    }
}

猜你喜欢

转载自regular.iteye.com/blog/1499937