很遗憾dubbo的几个创始人好像不维护dubbo了,最近有些人更新到了2.8.4:http://code.taobao.org/p/dubbox/src/trunk/dubbox/
dubbo的官网:http://dubbo.io/
此maven项目分三个子模块:sdk,app和web.其中sdk主要放一些公共的文件,app和web都依赖sdk.
一.在sdk模块:声明一个接口
package org.exam.sdk.service;
import org.exam.sdk.domain.User;
/**
* Created by xin on 15.12.27.
*/
public interface UserService {
User save(User user);
}
二.在app模块:
1.实现这个接口(在这里不赘述spring data jpa的使用)
package org.exam.app.service;
import com.alibaba.dubbo.config.annotation.Service;
import org.exam.sdk.domain.User;
import org.exam.app.repository.UserRepository;
import org.exam.sdk.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
/**
* Created by xin on 15.12.27.
*/
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
public User save(User user){
return userRepository.save(user);
}
}
2.写单元测试
package org.exam.app.service;
import org.exam.app.config.AppConfig;
import org.exam.sdk.base.ObjectId;
import org.exam.sdk.domain.User;
import org.exam.sdk.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import org.springframework.transaction.annotation.Transactional;
/**
* Created by xin on 2015/12/27.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader=AnnotationConfigContextLoader.class,classes={AppConfig.class})
@Transactional(transactionManager = "transactionManager")
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
@Rollback(false)
public void testInitData(){
User user=new User();
user.setId(new ObjectId().toString());
user.setUsername("username");
user.setPassword("password");
user.setEnable(true);
userService.save(user);
}
}
三.在web模块:
1.单元测试,看一下userService是否注入成功
package org.exam.web.service;
import com.alibaba.dubbo.config.annotation.Reference;
import org.exam.sdk.service.UserService;
import org.exam.web.config.AppConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* Created by xin on 2015/12/27.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={AppConfig.class})
public class UserServiceTest {
@Reference
private UserService userService;
@Test
public void testSave(){
System.out.println("userService = " + userService);
}
}
2.在controller使用
package org.exam.web.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import org.exam.sdk.domain.User;
import org.exam.sdk.service.UserService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("user")
public class UserController {
@Reference
private UserService userService;
@RequestMapping(value = "save")
public String save(User user) {
if (user.getId()==null){
user.setId(new Object().toString());
}
userService.save(user);
return "user/test";
}
}
四.再看看最关键的配置:
1.app的主要配置
package org.exam.app.config;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.spring.AnnotationBean;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
/**
* Created by xin on 15.12.27.
*/
@Configuration
@PropertySource("classpath:config.properties")
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = {"org.exam.app.repository"})
public class AppConfig implements EnvironmentAware {
private Environment env;
@Override
public void setEnvironment(Environment environment) {
env = environment;
}
/*与 相当.提供方扫描带有@com.alibaba.dubbo.config.annotation.Service的注解类*/
@Bean
public static AnnotationBean annotationBean() {
AnnotationBean annotationBean = new AnnotationBean();
annotationBean.setPackage("org.exam.app.service");//所以含有@com.alibaba.dubbo.config.annotation.Service的注解类都应在此包中,多个包名可以使用英文逗号分隔.
return annotationBean;
}
/*与 相当.*/
@Bean
public ApplicationConfig applicationConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setLogger("slf4j");
applicationConfig.setName(env.getProperty("dubbo.applicationName"));
return applicationConfig;
}
/*与 相当*/
@Bean
public RegistryConfig registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress(env.getProperty("dubbo.registryAddress"));
return registryConfig;
}
/*与 相当*/
@Bean
public ProtocolConfig protocolConfig(){
ProtocolConfig protocolConfig=new ProtocolConfig("dubbo",20880);
protocolConfig.setSerialization("java");//默认为hessian2,但不支持无参构造函数类,而这种方式的效率很低
return protocolConfig;
}
@Bean(destroyMethod = "close")
public DataSource dataSource() {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
try {
dataSource.setDriverClass(env.getProperty("db.driverClass"));
} catch (PropertyVetoException e) {
e.printStackTrace();
}
dataSource.setJdbcUrl(env.getProperty("db.jdbcUrl"));
dataSource.setUser(env.getProperty("db.user"));
dataSource.setPassword(env.getProperty("db.password"));
dataSource.setInitialPoolSize(Integer.valueOf(env.getProperty("db.initialPoolSize")));
dataSource.setAcquireIncrement(Integer.valueOf(env.getProperty("db.acquireIncrement")));
dataSource.setMinPoolSize(Integer.valueOf(env.getProperty("db.minPoolSize")));
dataSource.setMaxPoolSize(Integer.valueOf(env.getProperty("db.maxPoolSize")));
dataSource.setMaxIdleTime(Integer.valueOf(env.getProperty("db.maxIdleTime")));
dataSource.setIdleConnectionTestPeriod(Integer.valueOf(env.getProperty("db.idleConnectionTestPeriod")));
return dataSource;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
jpaVendorAdapter.setDatabase(Database.valueOf(env.getProperty("jpa.database")));
jpaVendorAdapter.setGenerateDdl(Boolean.parseBoolean(env.getProperty("jpa.generateDdl")));
jpaVendorAdapter.setShowSql(Boolean.parseBoolean(env.getProperty("jpa.showSql")));
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(dataSource());
emf.setPackagesToScan("org.exam.sdk.domain");
emf.setJpaVendorAdapter(jpaVendorAdapter);
return emf;
}
@Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
}
app模块的config.properties
#DATABASE START
db.driverClass=com.mysql.jdbc.Driver
db.jdbcUrl=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8
db.user=root
db.password=123456
#db.driverClass=oracle.jdbc.driver.OracleDriver
#db.jdbcUrl=jdbc:oracle:thin:@127.0.0.1:1521:orcl
#db.user=ieco2o
#db.password=ieco2o
db.initialPoolSize=5
db.acquireIncrement=3
db.minPoolSize=3
db.maxPoolSize=50
db.maxIdleTime=60
db.idleConnectionTestPeriod=120
#DATABASE END
#JPA START
jpa.generateDdl=true
jpa.showSql=true
#DEFAULT,DB2,DERBY,H2,HSQL,INFORMIX,MYSQL,ORACLE,POSTGRESQL,SQL_SERVER,SYBASE
jpa.database=MYSQL
#JPA END
#DUBBO START
dubbo.applicationName=provider-mall-app
dubbo.registryAddress=zookeeper://127.0.0.1:2181
#DUBBO END
2.web的主要配置
package org.exam.web.config;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.spring.AnnotationBean;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
/**
* Created by xin on 15/12/27.
*/
@Configuration
@PropertySource("classpath:config.properties")
@ComponentScan(basePackages = "org.exam.web.controller")
public class AppConfig implements EnvironmentAware {
private Environment env;
@Override
public void setEnvironment(Environment environment) {
env = environment;
}
/*与 相当.提供方扫描带有@com.alibaba.dubbo.config.annotation.Reference的注解类*/
@Bean
public static AnnotationBean annotationBean() {
AnnotationBean annotationBean = new AnnotationBean();
annotationBean.setPackage("org.exam.web.service,org.exam.web.controller");
return annotationBean;
}
/*与 相当.*/
@Bean
public ApplicationConfig applicationConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setLogger("slf4j");
applicationConfig.setName(env.getProperty("dubbo.applicationName"));
return applicationConfig;
}
/*与 相当*/
@Bean
public RegistryConfig registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress(env.getProperty("dubbo.registryAddress"));
return registryConfig;
}
/*与 相当*/
@Bean
public ProtocolConfig protocolConfig(){
ProtocolConfig protocolConfig=new ProtocolConfig("dubbo",20880);
protocolConfig.setSerialization("java");//默认为hessian2,但不支持无参构造函数类,而这种方式的效率很低
return protocolConfig;
}
/*dubbo end*/
}
web模块的config.properties
#DUBBO START
dubbo.applicationName=consumer-mall-web
dubbo.registryAddress=zookeeper://127.0.0.1:2181
#DUBBO END
五.其它不重要的,就省略,过行测试.先启动zookeeper(即使开发环境,注册中心也不使用广播,因为不稳定),再启动app的单元测试是否正常,再启动App,再启动web的单元测试是否正常,最后测试controller是否注入成功.
源码下载:http://download.csdn.net/detail/xiejx618/9383015