接口
//自定义注解
@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对象