首页 新闻 搜索 专区 学院

spring代理工厂注册接口代理对象出现问题

0
悬赏园豆:20 [待解决问题]

接口

//自定义注解
@Service(Serviceid = "userService")
//测试服务
public interface UserService {
    public User findByid(String id);
}

代理工厂

public class ServiceFactory<T> implements FactoryBean<T> {

    private Class<T> interfaceType;

    public Class<T> getInterfaceType() {
        return interfaceType;
    }

    public void setInterfaceType(Class<T> interfaceType) {
        this.interfaceType = interfaceType;
    }
	
   // public ServiceFactory(Class<T> interfaceType){
    //    this.interfaceType=interfaceType;
    //}

    @Override
    public T getObject() throws Exception {
        InvocationHandler handler=new ServiceProxy<>(interfaceType);
        return (T) Proxy.newProxyInstance(interfaceType.getClassLoader(),
                new Class[]{interfaceType},handler);
    }

    @Override
    public Class<?> getObjectType() {
        return interfaceType;
    }

    @Override
    public boolean isSingleton() {
        //单例
        return true;
    }

}

对象加载后置处理的的主要方法,将@Service注解的接口定义为bean

 @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        String defaultBasePackage="cn.sunline.myrpc";
        String basePackage= getEnvironment().getProperty("my.rpc.zookeeper.basePackages");
        if(basePackage.isEmpty()){
           basePackage=defaultBasePackage;
           logger.info("使用默认包路径",basePackage);
        }
        Set<Class<?>> set=scanPackage(basePackage);
        for (Class beanClazz:set
             ) {
            BeanDefinitionBuilder builder=BeanDefinitionBuilder.genericBeanDefinition();
            GenericBeanDefinition definition=(GenericBeanDefinition)builder.getRawBeanDefinition();
            Service service= getServiceAnnotations(beanClazz);
            String beanName="";
            if(service==null){
                break;
            }
            beanName =service.Serviceid().isEmpty()?beanClazz.getSimpleName():service.Serviceid();
            //使用set方法
            definition.getPropertyValues().add("interfaceType",beanClazz);
            //使用构造器
            // definition.getConstructorArgumentValues().addGenericArgumentValue(beanClazz);
            //这里beanClass指定的是生成bean的实例工厂 不是bean本身 这个工厂会构造接口的代理对象
            //FactoryBean是一种特殊的Bean,其返回的对象不是指定类的一个实例,是返回的 getObject方法返回的对象
            definition.setBeanClass(ServiceFactory.class);
            definition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE);
            beanDefinitionRegistry.registerBeanDefinition(beanName,definition);
        }
    }

然后在controller中@autowire Userservice的时候idea启动的时候有时候会报错,注入失败,有时候又不报,很奇怪。

Field service in cn.sunline.myrpc.test.TestController required a bean of type 'cn.sunline.myrpc.provider.service.UserService' that could not be found.

The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)

Action:

Consider defining a bean of type 'cn.sunline.myrpc.provider.service.UserService' in your configuration.

不报错的时候debug发现注入的service又有问题

还抛个异常,但是能用,搞不懂。求大神指点一下接口怎么注入,我看mybatis也是在bean加载的时候定义的代理mapper对象

丁丁有大丁丁的主页 丁丁有大丁丁 | 初学一级 | 园豆:182
提问于:2020-04-27 10:39
< >
分享
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册