最近在读Spring in Action4这本书,受其启发结合自己的业务,编写这个JavaConfig配置类+CXF的纯注解开发反例:
首先,准备环境:Spring4.x + cxf3.x + servlet3.x +Tomcat7,以上框架都要使用以上版本
其次,编写用于替代Web.xml的类AbstractAnnotationConfigDispatcherServletInitializer,
Spring3.2引入了一个便利的WebApplicationInitializer的基础实现,也就是AbstractAnnotationConfigDispatcherServletInitializer,配置该类可以用于启动DespatcherServlet创建的SpringMVC上下文和ContextLoaderListener创建的Spring应用上下文。
例:
package com.nari.config;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.apache.log4j.Logger;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import com.nari.coherence.listener.TaskServlet;
/**
* 该类用于替换web.xml配置文件:用于启动web容器
* @ClassName: StratApplicationContextInitializer
* @Description:
* @author: Fjw
* @date: 2018年1月17日 上午8:57:40
*/
public class StratApplicationContextInitializer
extends AbstractAnnotationConfigDispatcherServletInitializer{
private static final Logger logger = Logger.getLogger(StratApplicationContextInitializer.class);
/**
* 返回带有@Configuration注解的类,将会用来配置ContextLoaderListener创建的应用上下文中的bean
* ApplicationContext(里面包含了由该上下文创建的所有bean)
*/
@Override
protected Class>[] getRootConfigClasses() {
// 创建一个配置类,用于registerContextLoaderListener底层方法的加载使用
logger.info(">>>>>>root配置类初始化<<<<<<<<<");
return new Class>[]{RootConfig.class};
}
/**
* 返回带有@Configuration注解的类
* 用来返回由DispatcherServlet创建的应用上下文
* DispatcherServlet(里面包含了由该上下文创建的所有bean)
*
* 本项目未用到DispatcherServlet
*/
@Override
protected Class>[] getServletConfigClasses() {
logger.info(">>>>>>web配置类初始化<<<<<<<<<");
return null;
}
/**
* 一个或多个路径映射到DispatcherServlet上
* 本项目未用到
*/
@Override
protected String[] getServletMappings() {
logger.info(">>>>>>映射根路径初始化<<<<<<<<<");
return new String[]{ "/" };//请求路径映射,根路径
}
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
// 在Web容器中添加一个用于初始化前置缓存的Servlet
Dynamic frontServlet = servletContext.addServlet("InitListener", TaskServlet.class);
frontServlet.setLoadOnStartup(2);
// 在Web容器中添加一个用于启动CXF的Servlet
Dynamic cxfServlet = servletContext.addServlet("cxf", CXFServlet.class);
logger.info(">>>>>>添加CXF的Servlet<<<<<<<<<");
cxfServlet.addMapping("/ws/*"); // 映射Servlet的路径
cxfServlet.setLoadOnStartup(1);
// 在Web容器中添加一个Filter
javax.servlet.FilterRegistration.Dynamic encodFilter = servletContext.addFilter("encodingFilter", CharacterEncodingFilter.class);
logger.info(">>>>>>添加一个编码集的过滤器<<<<<<<<<");
encodFilter.addMappingForServletNames(null, false, "/*");
encodFilter.setInitParameter("encoding", "UTF-8");
encodFilter.setInitParameter("forceEncoding", "true");
registerContextLoaderListener(servletContext);
}
}
第三:创建JavaConfig配置类 之 先编写RootConfig配置类
package com.nari.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.nari.webservice.IEIGWSForPower;
import com.nari.webservice.impl.IEIGWSForPowerImpl;
/**
* 用来返回由ContextLoaderListener创建的应用上下文 ApplicationContext(里面包含了由该上下文创建的所有bean)
* @ClassName: RootConfig
* @Description:
* @author: Fjw
* @date: 2018年1月17日 上午9:17:27
*/
@Configuration
@EnableTransactionManagement
@EnableAspectJAutoProxy // 该注解用于启用Spring的自动代理功能
@Import({CXFConfig.class,DbcpDataSourceConfig.class,ServiceConfig.class}) // 该注解用于将其他配置类整合到本配置类中
@ComponentScan(basePackages=("com.nari")) // 启动注解包扫描组件,扫描该包及其子包
public class RootConfig {
/**
* 以下三个是SPring上下文启动时,设置的三个初始化参数(在base.properties里面设置),
*/
@Value("${corePoolSize}")// 该注解用于读取当前上文中的属性值
private String corePoolSize;
@Value("${maximumPoolSize}")
private String maximumPoolSize;
@Value("${keepAliveTime}")
private String keepAliveTime;
// 创建提供WenService的服务类
@Bean(name = "iEIGWSForPower")
public IEIGWSForPower getIEIGWSForPower(){
return new IEIGWSForPowerImpl();
}
}
附:
其次,准备base.properties, log4j.properties连个properties文件,
base.properties:
#database connection
dataSource.connection.url.mid=jdbc:oracle:thin:@(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = xe) ) )
dataSource.connection.driver_class.mid=oracle.jdbc.driver.OracleDriver
dataSource.connection.username.mid=scott
dataSource.connection.password.mid=tiger
#dataSource.default_schema.mid=fzptsea
#数据库连接池
datasource.initialSize=5
datasource.minIdle=5
datasource.maxActive=50
#连接超时设置
datasource.maxWait=60000
#check leisure connection and close
datasource.timeBetweenEvictionRunsMillis=60000
第四:创建JavaConfig配置类 之 先编写ServiceConfig配置类
package com.nari.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.nari.service.cj.HebeiCommandCJService;
import com.nari.service.cj.impl.HebeiCommandCJServiceImpl;
import com.nari.service.cj.impl.MeasureService;
import com.nari.service.mid.HebeiCommandMidService;
import com.nari.service.mid.impl.HebeiCommandMidServiceImpl;
import com.nari.service.quartz.HebeiQuartzService;
import com.nari.service.quartz.impl.HebeiQuartzServiceImpl;
import com.nari.util.UploadUtils;
/**
*
* @ClassName: ServiceConfig
* @Description: 服务类的配置类
* @author: Fjw
* @date: 2018年1月17日 下午4:44:19
*/
@Configuration
public class ServiceConfig {
@Bean(name = "hebeiCommandCJService")
public HebeiCommandCJService getHebeiCommandCJService(){
return new HebeiCommandCJServiceImpl();
}
@Bean(name = "hebeiCommandMidService")
public HebeiCommandMidService getHebeiCommandMidService(){
return new HebeiCommandMidServiceImpl();
}
@Bean(name = "hebeiQuartzService")
public HebeiQuartzService getHebeiQuartzService(){
return new HebeiQuartzServiceImpl();
}
@Bean(name = "measureService")
public HebeiCommandCJService getMeasureService(){
return new MeasureService();
}
@Bean(name = "uploadUtils")
public UploadUtils getUploadUtils(){
return new UploadUtils();
}
}
依次为例配置Data Access Object 的配置类。
第五,创建cxf的JavaConfig 配置类
package com.nari.config;
import javax.xml.ws.Endpoint;
import org.apache.cxf.Bus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import com.nari.service.cj.HebeiCommandCJService;
import com.nari.webservice.IEIGWSForPower;
/**
* @ClassName: RootConfig
* @Description: CXF的配置类
* @author: Fjw
* @date: 2018年1月17日 上午9:17:27
*/
@Configuration
@ImportResource({"classpath:META-INF/cxf/cxf.xml"})// 该注解用于将位于类路径下的.xml配置文件导入JavaConfig类
public class CXFConfig {
@Autowired
private IEIGWSForPower iEIGWSForPower;
/**
* 用于拦截所有的访问iEIGWSForPower服务的请求
*/
@Autowired
private Bus bus;
@Bean(name = "serviceEndpoint")
public Endpoint getServiceEndpoint(){
// 参数1:请求拦截器(cxf自带);参数2:提供服务的接口(注入时注入的是实现类)
EndpointImpl endpoint = new EndpointImpl(bus, iEIGWSForPower);
LOGGER.info(">>>>>>>>>>CXF服务发布了<<<<<<<<<<<");
endpoint.publish("/iEIGWSForPowerWS");
System.out.println(hebeiCommandCJService.toString());
return endpoint;
}
}