1、目的
实现将一个接口动态代理,并将该代理对象在spring容器初始化完成前注册到spring容器中。实现可以通过@Autowired等注释或其他方法从spring容器中获取该代理对象。
2、灵感来源
翻mybatis的源代码获得,
3、代码
源代码下载
3.1、接口类
| 12
 3
 4
 
 | public interface TestService {
 public String sayHello();
 }
 
 | 
3.2、代理类
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | public class MyProxy implements InvocationHandler{
 private Class<?> interfaceClass;
 
 public Object bind(Class<?> cls) {
 this.interfaceClass = cls;
 return Proxy.newProxyInstance(cls.getClassLoader(), new Class[] {interfaceClass}, this);
 }
 
 @Override
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
 return "hello world";
 }
 
 }
 
 | 
3.3、代理工厂
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 
 | public class MyProxyFactory<T> implements FactoryBean<T> {
 private Class<T> interfaceClass;
 public Class<T> getInterfaceClass() {
 return interfaceClass;
 }
 public void setInterfaceClass(Class<T> interfaceClass) {
 this.interfaceClass = interfaceClass;
 }
 @Override
 public T getObject() throws Exception {
 return (T) new MyProxy().bind(interfaceClass);
 }
 
 @Override
 public Class<?> getObjectType() {
 return interfaceClass;
 }
 
 @Override
 public boolean isSingleton() {
 
 return true;
 }
 
 }
 
 | 
3.4、注册spring容器
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 
 | @Componentpublic class MyRegistryBean implements ApplicationContextAware,BeanDefinitionRegistryPostProcessor{
 
 private ApplicationContext ctx;
 @Override
 public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
 }
 @Override
 public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
 
 Class<?> cls = TestService.class;
 BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(cls);
 GenericBeanDefinition definition = (GenericBeanDefinition) builder.getRawBeanDefinition();
 definition.getPropertyValues().add("interfaceClass", definition.getBeanClassName());
 definition.setBeanClass(MyProxyFactory.class);
 definition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE);
 
 beanDefinitionRegistry.registerBeanDefinition("testService", definition);
 }
 @Override
 public void setApplicationContext(ApplicationContext ctx) throws BeansException {
 this.ctx = ctx;
 }
 
 }
 
 | 
3.5、测试
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | @RunWith(SpringJUnit4ClassRunner.class)  @ContextConfiguration({"classpath*:applicationContext.xml"})
 public class Start {
 
 @Autowired
 TestService testService;
 
 @Test
 public void test() {
 System.out.println(testService.sayHello());
 }
 }
 
 | 
控制台成功输出“hello world”,即成功在spring容器初始化完成前,将TestService接口代理,并将代理类注册到spring容器中。