SSH项目实战OA-Zookeeper管理配置文件

为什么要用统一配置?

我们做项目时用到的配置比如数据库配置等...我们都是写死在项目里面,如果需要更改,那么也是的修改配置文件然后再投产上去,那么问题来了,如果做集群的呢,有100台机器,这时候做修改那就太不切实际了;那么就需要用到统一配置管理啦。

解决思路

一,把公共配置抽取出来,存储到数据库中.

每个需要配置信息的模块都从数据库中获取.但是这个方法明显不符合我们系统的架构,无论是dao工程或者是web工程都要直接操作数据库,并且需要配置hibernate,这样既不安全也不方便.另外,如果需要修改配置文件,必须手动地让工程重新从数据库获取数据.

这个方法对于我们分布式系统肯定是不是呀的啦.但我们还有第二种方案.

二,把公共配置抽取出来,存储到数据库中,并且把配置发布到Zookeeper中.

这个方法虽然同样是从数据库中获取配置信息,但也有所不同.这种方法只需要有一个工程操作数据库,读取数据库中的配置信息.那么其他工程要如何获取到配置信息呢?当一个工程A从数据库中获取到配置信息之后,立即将配置信息发布到Zookeeper中,而其他工程只需要从Zookeeper中获取配置信息,而不需要操作数据库.另外,Zookeeper提供监听器功能,无论哪个工程修改了Zookeeper中的配置信息,其他工程都能知道,并且重新从Zookeeper中获取配置信息,而工程A也会将修改的配置信息更新到数据库中.

 

zookeeper实现统一配置管理

首先,我们需要在数据库中增加一个实体表Config.

 

在新建完实体表后,就要在工程中添加实体类.由于这个类会被所有工程所用到,所以我们要把Config放在公共工程OA-common中

在OA-common中添加com.QEcode.OA.common.pojo包.

新建Config实体类

public class Config implements Serializable {
    Long id;
    String configName;
    String configValue;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getConfigName() {
        return configName;
    }
    public void setConfigName(String configName) {
        this.configName = configName;
    }
    public String getConfigValue() {
        return configValue;
    }
    public void setConfigValue(String configValue) {
        this.configValue = configValue;
    }
    public Config(){
	
    }
    public Config(String configName, String configValue) {
	super();
	this.configName = configName;
	this.configValue = configValue;
    }
    
}

 

搭建OA-portal-dao工程

 

 

在pom.xml文件中添加依赖

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.QEcode</groupId>
    <artifactId>OA-portal</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>OA-portal-dao</artifactId>
  
   <dependencies>
  	<!-- hibernate -->
	<dependency>
		<groupId>org.hibernate</groupId>
		<artifactId>hibernate-core</artifactId>
	</dependency>
  	<!-- MySql -->
      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
      </dependency>
      <!-- 连接池 -->
      <dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>druid</artifactId>
      </dependency>
      <!-- Spring -->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-context</artifactId>
       </dependency>
       <dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
		</dependency>
		
		<!-- zookeeper的客户端,你要连接zookeeper,需要把以下两个jar包加进来 -->
		<dependency>
		    <groupId>org.apache.zookeeper</groupId>
		    <artifactId>zookeeper</artifactId>
		</dependency>
		<dependency>
		    <groupId>com.github.sgroschupf</groupId>
		    <artifactId>zkclient</artifactId>
		</dependency>
  </dependencies>
  
  
  
</project>

 

搭建OA-portal-interface工程

这个工程暂时不用添加依赖

 

搭建OA-portal-service工程

 

 

在pom.xml中添加依赖,可以把OA-system-service中的依赖复制过来

 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.QEcode</groupId>
    <artifactId>OA-portal</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>OA-portal-service</artifactId>
  <packaging>war</packaging>
  <dependencies>
		<!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
        <dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
		</dependency>
		<!-- dubbo相关 -->
		<dependency>
		    <groupId>com.alibaba</groupId>
		    <artifactId>dubbo</artifactId>
		    <!-- 排除依赖 -->
		    <exclusions>
		        <exclusion>
		            <groupId>org.springframework</groupId>
		            <artifactId>spring</artifactId>
		        </exclusion>
		        <exclusion>
		            <groupId>org.jboss.netty</groupId>
		            <artifactId>netty</artifactId>
		        </exclusion>
		    </exclusions>
		</dependency>
		
		<!-- zookeeper的客户端,你要连接zookeeper,需要把以下两个jar包加进来 -->
		<dependency>
		    <groupId>org.apache.zookeeper</groupId>
		    <artifactId>zookeeper</artifactId>
		</dependency>
		<dependency>
		    <groupId>com.github.sgroschupf</groupId>
		    <artifactId>zkclient</artifactId>
		</dependency>


		<dependency>
			<groupId>com.QEcode</groupId>
			<artifactId>OA-portal-dao</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>com.QEcode</groupId>
			<artifactId>OA-portal-interface</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		
		<dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>
		
		
		
  </dependencies>
</project>

 

 

service层

接下来,把OA-system-service中resources目录下所有文件复制到OA-portal-service中

 

修改applicationContext-dao.xml文件.

将spring扫描的包改为com.QEcode.OA.portal.dao

 

 

完整的applicationContext-dao.xml文件如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        ">
     <!-- 加载配置文件 -->
    <context:property-placeholder location="classpath:resource/*.properties"/>    
     <!-- 配置spring容器创建时要扫描的包 -->
    <context:component-scan base-package="com.QEcode.OA.portal.dao"></context:component-scan>   
     <!-- 配置hibernateTemplate,用于持久层 -->
   <bean id="hibernateTemplate" class="org.springframework.orm.hibernate5.HibernateTemplate">
   		<property name="sessionFactory" ref="sessionFactory"></property>
   </bean>
   <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
   		<property name="dataSource" ref="dataSource"/>
		<!-- hibernate参数设置 -->
		<property name="hibernateProperties">
			<props>
				<!-- 数据库方言 -->
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				<!-- 显示sql语句-->
				<prop key="hibernate.show_sql">true</prop>
				<!-- 格式化SQL语句 -->
				<prop key="hibernate.format_sql">true</prop>
				<!-- create:根据映射关系生成表 -->
				<prop key="hibernate.hbm2ddl.auto">update</prop>
				<prop key="current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</prop>
			</props>
		</property>
   </bean>
	 <!-- 数据库连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
        destroy-method="close">
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="maxActive" value="${jdbc.maxActive}" />
        <property name="minIdle" value="${jdbc.minIdle}" />
    </bean>   
</beans>

 

修改applicationContext-service.xml文件.

修改spring扫描的包

修改在注册中心注册的名字

修改端口号,因为20880被OA-system-service所使用

完整的applicationContext-service.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
    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.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://code.alibabatech.com/schema/dubbo 
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        ">

	<!-- 配置spring容器创建时要扫描的包 -->
    <context:component-scan base-package="com.QEcode.OA.portal.service.impl"></context:component-scan>
	<!-- 使用dubbo发布服务 -->
	<!-- 提供方应用信息,用于计算依赖关系 -->
	<dubbo:application name="OA-portal" />
	<dubbo:registry protocol="zookeeper" address="${dubbo.address}" />
	<!-- 用dubbo协议在20881端口暴露服务 -->
	<dubbo:protocol name="dubbo" port="20881" />
	<!-- 声明需要暴露的服务接口 -->
	

</beans>

修改applicationContext-trans.xml文件.

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        ">
    <!-- 配置事务管理器 -->
   <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
   		<property name="sessionFactory" ref="sessionFactory"></property>
   </bean>     
   
	<!-- 通知 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <!-- 传播行为 -->
            <tx:method name="save*" propagation="REQUIRED" />
            <tx:method name="insert*" propagation="REQUIRED" />
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="create*" propagation="REQUIRED" />
            <tx:method name="delete*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="find*" propagation="SUPPORTS" read-only="true" />
            <tx:method name="select*" propagation="SUPPORTS" read-only="true" />
            <tx:method name="get*" propagation="SUPPORTS" read-only="true" />
        </tx:attributes>
    </tx:advice>
    <!-- 切面 -->
    <aop:config>
        <aop:advisor advice-ref="txAdvice"
            pointcut="execution(* com.QEcode.OA.portal.service.*.*(..))" />
    </aop:config>
        
        
</beans>       

 

修改web.xml文件

将OA-system-service的web.xml文件中spring监听器复制过来

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <display-name>OA-portal-service</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
 
   <!-- 加载spring容器 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/applicationContext-*.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
 
</web-app>

 

Dao层

 

在OA-portal-dao中src/main/java中新建 com.QEcode.OA.portal.dao.impl包.

在包下新建ZookeeperDao类,由于这个类比较简单,所以不用创建接口了.

ZookeeperDao类内容如下:

@Repository
public class ZookeeperDao {
    
    @Resource(name="hibernateTemplate")
    protected HibernateTemplate hibernateTemplate;
    
    /**
     * @Description:从数据库中获取所有配置信息
     * @return
     */
    public List<Config> findConfigFromDB(){
	//查询语句
	String sql = "select *from config";
	Session session = hibernateTemplate.getSessionFactory().openSession();
	//执行查询
	Query query = session.createSQLQuery(sql);
	//获取查询结果
	List<Object[]>  list = query.list();
	List<Config> configs = new ArrayList<Config>();
	//将结果中的内容存到Cofig列表中
	for(Object[] objs : list){
	    Config config = new Config((String)objs[0],(String)objs[1]);
	    configs.add(config);
	}
	return configs;
    session.close();
    }
    
    /**
     * @Description:将配置文件上传到数据库中
     * @param configName
     * @param configValue
     */
    public void saveConfigToDB(String configName,String configValue){
	String sql = "insert into config(config_name,config_value) value('"+configName+"','"+configValue+"')";
	Session session = hibernateTemplate.getSessionFactory().openSession();
	session.createSQLQuery(sql);
    session.close();
    }

}

 

可以看到,我们虽然使用了HibernateTemplate对象,但是我们依然使用原始的sql语句来操作数据库,这是因为Cofig实体类并没有在hibernate中配置或者使用注解来标识其与数据库中的config表相关联,所以我们不能直接通过hql语句来操作数据库.

 

 

 

 

service层

Dao层用于获取数据库中的配置信息,而service层则是将Dao层从数据库中获取到的信息上传搭到Zookeeper中.

在OA-portal-interface工程中新建com.QEcode.OA.portal.service包

 

在该包下创建接口ZookeeperService,该接口只有一个方法,syncConfigToZk,将配置信息上传到Zookeeper中

public interface ZookeeperService {

    public void syncConfigToZk();

}

 

 

在OA-portal-servic-工程下的com.QEcode.OA.portal.service.impl包新建一个类ZookeeperServiceImpl,实现了ZookeeperService

在创建好ZookeeperServiceImpl类之后,先不用急着写内容,因为OA-portal-dao工程是新建的,所以还没有在OA-portal-service中添加

OA-portal-dao依赖.

<dependency>

<groupId>com.QEcode</groupId>

<artifactId>OA-portal-dao</artifactId>

<version>0.0.1-SNAPSHOT</version>

</dependency>

现在OA-portal-service工程的pom.xml文件如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.QEcode</groupId>
    <artifactId>OA-portal</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>OA-portal-service</artifactId>
  <packaging>war</packaging>
  <dependencies>
		<!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
        <dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
		</dependency>
		<!-- dubbo相关 -->
		<dependency>
		    <groupId>com.alibaba</groupId>
		    <artifactId>dubbo</artifactId>
		    <!-- 排除依赖 -->
		    <exclusions>
		        <exclusion>
		            <groupId>org.springframework</groupId>
		            <artifactId>spring</artifactId>
		        </exclusion>
		        <exclusion>
		            <groupId>org.jboss.netty</groupId>
		            <artifactId>netty</artifactId>
		        </exclusion>
		    </exclusions>
		</dependency>
		
		<!-- zookeeper的客户端,你要连接zookeeper,需要把以下两个jar包加进来 -->
		<dependency>
		    <groupId>org.apache.zookeeper</groupId>
		    <artifactId>zookeeper</artifactId>
		</dependency>
		<dependency>
		    <groupId>com.github.sgroschupf</groupId>
		    <artifactId>zkclient</artifactId>
		</dependency>


		<dependency>
			<groupId>com.QEcode</groupId>
			<artifactId>OA-portal-dao</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>com.QEcode</groupId>
			<artifactId>OA-portal-interface</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		
		<dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>
		
		
		
  </dependencies>
</project>

好,下面让我们来实现将配置信息上传到Zookeeper中

@Service
public class ZookeeperServiceImpl implements ZookeeperService {
    
    @Autowired
    private ZookeeperDao zookeeperDao;
    
    @Value("${zookeeper.address}")
    private String address;
    
    private String path = "/config/";
    /**
     * @Description:将配置信息上传到Zookeeper中
     */
    public void syncConfigToZk(){
	ZkClient zk = new ZkClient(address);
	List<Config> configs = zookeeperDao.findConfigFromDB();
	for(Config config:configs){
	    //判断在Zookeeper中是否已经存在该配置信息并且配置信息与数据库中的信息一样
	   
	    //如果没有该节点
	    if(!zk.exists(path+config.getConfigName())){
		 //在Zookeeper中/config/目录下创建子节点
		   zk.createPersistent(path+config.getConfigName(),config.getConfigName());
	    }else{
		//如果存在该节点,但配置信息不一样
		 String value = zk.readData(path+config.getConfigName());
		if(value.equals(config.getConfigValue())){
		    zk.createPersistent(path+config.getConfigName(),config.getConfigName());
		}
	    }
	}
	zk.close();
    }
    
}

 

@Value("zookeeper.address")表示从resources目录下的*.properties中获取value,当然前提是,你在spring的配置文件中导入*.properties

我们在applicationContext-dao.xml中已经配置了

同时,zookeeper.address在resource.properties文件中配置

 

最后,要通过dubbo把服务发布出去

在OA-portal-service工程中的applicationContext-service.xml中配置dubbo信息

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
    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.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://code.alibabatech.com/schema/dubbo 
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        ">

	<!-- 配置spring容器创建时要扫描的包 -->
    <context:component-scan base-package="com.QEcode.OA.portal.service.impl"></context:component-scan>
	<!-- 使用dubbo发布服务 -->
	<!-- 提供方应用信息,用于计算依赖关系 -->
	<dubbo:application name="OA-portal" />
	<dubbo:registry protocol="zookeeper" address="${dubbo.address}" />
	<!-- 用dubbo协议在20881端口暴露服务 -->
	<dubbo:protocol name="dubbo" port="20881" />
	<!-- 声明需要暴露的服务接口 -->
	<!-- Zookeeper服务 -->
	<!-- <dubbo:service interface="com.QEcode.OA.portal.service.ZookeeperService" ref="zookeeperServiceImpl"></dubbo:service>
	 -->
	
		
</beans>

 

最后,我们需要再解压一个新的Tomcat并改名为OA-portal-service,修改该Tomcat的端口为8002 8083 8012

controller层

引用dubbo服务

首先将关于dubbo的依赖复制到OA-portal-web工程的pom.xml

<!-- dubbo相关 -->

<dependency>

    <groupId>com.alibaba</groupId>

    <artifactId>dubbo</artifactId>

    <!-- 排除依赖 -->

    <exclusions>

        <exclusion>

            <groupId>org.springframework</groupId>

            <artifactId>spring</artifactId>

        </exclusion>

        <exclusion>

            <groupId>org.jboss.netty</groupId>

            <artifactId>netty</artifactId>

        </exclusion>

    </exclusions>

</dependency>

 

<!-- zookeeper的客户端,你要连接zookeeper,需要把以下两个jar包加进来 -->

<dependency>

    <groupId>org.apache.zookeeper</groupId>

    <artifactId>zookeeper</artifactId>

</dependency>

<dependency>

    <groupId>com.github.sgroschupf</groupId>

    <artifactId>zkclient</artifactId>

</dependency>

 

完整的pom.xml文件如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.QEcode</groupId>
    <artifactId>OA-portal</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>OA-portal-web</artifactId>
  <packaging>war</packaging>
  
  <dependencies>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
        <!-- JSP相关 -->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jsp-api</artifactId>
            <scope>provided</scope>
        </dependency>
        <!-- struts2 -->
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-core</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-spring-plugin</artifactId>
		</dependency>
  </dependencies>
  
</project>

然后,把OA-portal-service工程下src/main/resources/resource目录中的resource.properties文件复制到OA-portal-web工程下

 

修改spring目录下的applicationContext.xml,添加dubbo约束

 

然后在applicationContext.xml中添加dubbo引用

 

完整的applicationContext.xml文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        ">
    <!-- 配置spring容器创建时要扫描的包 -->
    <context:component-scan base-package="com.QEcode.OA.controller"></context:component-scan>
    
</beans>        

在controller层,我们要完成的任务是从Zookeeper中获取到配置信息,不过我们要把从Zookeeper获取配置信息的功能放在OA-common工程,因为这个功能会被其他工程所用到.

在OA-common工程的sec/main/java目录下新建包com.QEcode.OA.common.utils

 

由于我们要在OA-common工程内使用Zookeeper,所以要在pom.xml文件添加Zookeeper的依赖

 <!-- zookeeper的客户端,你要连接zookeeper,需要把以下两个jar包加进来 -->

<dependency>

    <groupId>org.apache.zookeeper</groupId>

    <artifactId>zookeeper</artifactId>

</dependency>

<dependency>

    <groupId>com.github.sgroschupf</groupId>

    <artifactId>zkclient</artifactId>

</dependency>

 

完整的pom.xml文件如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.QEcode</groupId>
    <artifactId>OA-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>OA-common</artifactId>
  
 <!-- 依赖工具类的jar包 -->
    <dependencies>      
        <!-- 时间操作组件 -->          
         <dependency>
             <groupId>joda-time</groupId>
             <artifactId>joda-time</artifactId>
         </dependency>
         <!-- Apache工具组件 -->
         <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
         </dependency>
         <dependency>     
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-io</artifactId>
         </dependency>
         <dependency>         
             <groupId>commons-net</groupId>
             <artifactId>commons-net</artifactId>
         </dependency>
         <!-- Jackson Json处理工具包 -->
         <dependency>
             <groupId>com.fasterxml.jackson.core</groupId>
             <artifactId>jackson-databind</artifactId>
         </dependency>
         <!-- quartz任务调度框架 -->
         <dependency>
             <groupId>org.quartz-scheduler</groupId>
             <artifactId>quartz</artifactId>
         </dependency>
         <!-- 单元测试 -->
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <scope>test</scope>
         </dependency>
         <!-- 日志处理 -->
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-log4j12</artifactId>
         </dependency>
         <!-- zookeeper的客户端,你要连接zookeeper,需要把以下两个jar包加进来 -->
		<dependency>
		    <groupId>org.apache.zookeeper</groupId>
		    <artifactId>zookeeper</artifactId>
		</dependency>
		<dependency>
		    <groupId>com.github.sgroschupf</groupId>
		    <artifactId>zkclient</artifactId>
		</dependency>
    </dependencies>

</project>

 

添加完依赖后,在utils包下创建ZookeeperUtils类

 

具体内容如下:

public class ZookeeperUtils {
    //Zookeeper地址
    private static String address = "192.168.43.150:2181";
    //配置信息所在节点
    private static String path =  "/config/"; 
    
    /**
     * @Description:根据配置信息名称获取配置信息内容
     * @param configName
     * @return
     */
    public static Config getConfig(String configName){
	if(zk.exists(path+configName)){
	    String configValue = zk.readData(path+configName);
	    Config config = new Config(configName, configValue);
	    return config;
	}
	return null;
    }
    
    
}

我们把配置信息上传到Zookeeper的config节点下,但是之前我们是没有创建这个节点的,所以,我们要先在Zookeeper中创建config节点

在虚拟机中启动Zookeeper

 

使用Zookeeper服务端

 

创建config节点

 

查看Zookeeper,可以看到已经创建了config节点

至此,我们已经基本实现Zookeeper管理配置文件功能,但我们还没指定工程什么时候从数据库获取配置信息并且上传到Zookeeper中.考虑到这个功能的性质,我们需要在OA-portal-service启动的时候就要从数据库中获取配置信息,并上传到Zookeeper中.所以,我们需要配置一个监听器,在项目启动的时候,就调用这个功能.

在OA-portal-service工程下的src/main/java目录中新建包com.QEcode.OA.portal.listener

在该包下创建InitServletContextListener类,并实现ServletContextListener接口

在此之前,我们需要在pom.xml中添加servlet的依赖

<dependency>

            <groupId>javax.servlet</groupId>

            <artifactId>servlet-api</artifactId>

            <scope>provided</scope>

        </dependency>

public class InitServletContextListener implements ServletContextListener {

    /**
     * @Description:初始化
     * @param sce
     */
    @Override
    public void contextInitialized(ServletContextEvent sce) {
	ServletContext application = sce.getServletContext();
	//得到service实例
	ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(application);
	ZookeeperService zookeeperService = (ZookeeperService) ac.getBean("zookeeperServiceImpl");
	//将配置信息上传到Zookeeper中
	zookeeperService.syncConfigToZk();
	System.out.println("------------配置信息上传成功------------");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
	

    }

}

从上面代码可以看到,我们获取bean的方式和以往的不同,不是使用注解来注入,而是要获取WebApplicationContext容器,再从容器中获取.

为什么会这样呢?因为以往我们是在spring容器中使用注解,而Listener是由servlet容器管理的.而servlet容器并不认得@Autowired注解,所以不能直接使用注解来注入bean,那么怎么在spring容器外面获取到spring容器bean实例的引用呢?这就需要用到spring为我们提供的WebApplicationContextUtils工具类,该工具类的作用是获取到spring容器的引用,进而获取到我们需要的bean实例

最后,还要在web.xml中配置我们的监听器


 <!-- 用于初始化配置信息 -->
   <listener>
  	<listener-class>com.QEcode.OA.portal.listener.InitServletContextListener</listener-class>
  </listener>
  <context-param>
  	<param-name>contextConfigLocation</param-name>
  	<param-value>classpath:spring/applicationContext-*.xml</param-value>
  </context-param>

===============================================================================================

在写博客的时候,可能在项目中有一些问题没有被发现,在我修改后,忘记写到博客上,所以我将这个项目上传到github上,大家可以在github上获取项目的代码

下面是github地址,大家Fork and Star


OA-Reconsitution
 

猜你喜欢

转载自blog.csdn.net/QEcode/article/details/84557013