公司维护的老项目使用的dubbo2.5.3 (以前只用没搭过工程)。 最近想用springboot集成它。于是写了以下代码
@Configuration
public class DubboConfig {
@Value("${sysGlobal.applicationName}") //@value 在此处因为AnnotationBean 的存在是获取不到值的,可以换个方式获取。百度一下网上很多例子
private String applicationName;
@Value("${his.zookeeper.address}")
private String zookeeperAddress;
@Value("${his.dubbo.service.portal}")
private Integer dubboPortal;
@Value("${his.dubbo.service.host}")
private String serviceHost;
@Bean
public ApplicationConfig applicationConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName(applicationName);
applicationConfig.setLogger("slf4j");
return applicationConfig;
}
@Bean
public Object registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setProtocol("zookeeper");
registryConfig.setAddress(zookeeperAddress);
registryConfig.setCheck(false);
return registryConfig;
}
@Bean
public ProtocolConfig protocolConfig() {
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.setName("dubbo");
protocolConfig.setPort(dubboPortal);
protocolConfig.setHost(serviceHost);
return protocolConfig;
}
@Bean
public ProviderConfig providerConfig() {
ProviderConfig providerConfig = new ProviderConfig();
providerConfig.setTimeout(15000);
return providerConfig;
}
@Bean
public AnnotationBean annotationBean(){
//applicationContext.addBeanFactoryPostProcessor();
AnnotationBean annotationBean = new AnnotationBean();
annotationBean.setPackage("com.dubbo.service");
return annotationBean;
}
}
可是启动项目之后发现没有加载dubbo和连接zookeeper的日志。但是打印了dubbo找不到log4j的日志。原因是扫描的包里没有@service的文件。
只要在包里加上个接口使用@service标记。dubbo的AnnotationBean启动时就会扫描,然后加载连接zookeeper了。
以上是服务端的事。
之后需要给一个老项目集成dubbo客户端。使用springmvc。但是按照xml配置后启动也只是打印了找到到log4j的日志没有初始化dubbo的日志。倒是在使用到@Reference标记的类时会进行dubbo初始化。客户端xml如下。使用<context-param>加载的xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
"
default-autowire="byName">
<dubbo:application name="${service.web}" logger="slf4j"/>
<dubbo:registry protocol="zookeeper" address="${zookeeper.address}" check="false" timeout="5000" />
<dubbo:consumer timeout="5000" retries="0" check="false"/>
<dubbo:annotation package="com.hisLogin.controller,com.dubbo.service"/>
</beans>
一番百度之后总算有所发现。调用dubbo service的是一个controller类。类里加上了@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)。代码如下
@Controller("LoginController")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class LoginController extends XXXXXX{
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)只有在使用bean的时候才会初始化。故只有调用改类的时候dubbo AnnotationBean 里的 postProcessBeforeInitialization 才会触发,检测到@Reference进行dubbo初始化。 <context-param>使用的是ApplicationContext进行bean加载。
spring什么时候实例化bean
第一:如果你使用BeanFactory作为Spring Bean的工厂类,则所有的bean都是在第一次使用该Bean的时候实例化
第二:如果你使用ApplicationContext作为Spring Bean的工厂类,则又分为以下几种情况:
(1):如果bean的scope是singleton的,并且lazy-init为false(默认是false,所以可以不用设置),则ApplicationContext启动的时候就实例化该Bean,并且将实例化的Bean放在一个map结构的缓存中,下次再使用该Bean的时候,直接从这个缓存中取
(2):如果bean的scope是singleton的,并且lazy-init为true,则该Bean的实例化是在第一次使用该Bean的时候进行实例化
(3):如果bean的scope是prototype的,则该Bean的实例化是在第一次使用该Bean的时候进行实例化
如果项目使用的logback日志可以使用 log4j-over-slf4j输出dubbo日志到slf4j