javascript
SpringMVC学习(五)——零配置实现SpringMVC
文章目錄
- 1、引言
- 2、搭建過程
- 2.1 開發環境搭建
- 2.2 項目搭建
- 2.2.1 首先看`web.xml`配置
- 2.2.2 增加`WebApplicationInitializer`的實現類
- 2.2.3 增加`ApplicationContextConfig`配置類
- 2.2.4 增加`application.properties`配置文件
- 2.2.5 增加`WebSpringMVCServletConfig`配置類
- 2.3 測試結果
- 2.3.1 增加`UserInfoService`以及實現類`UserInfoServiceImpl`
- 2.3.2 增加`HelloWorldController`
- 2.3.3 啟動`tomcat`進行測試
- 3、總結
1、引言
從開始使用SpringMVC的那一天我就開始想如何減少SpringMVC的配置,如何使用更簡潔的方式搭建SpringMVC框架。通過學習和總結實現了本文說的零配置實現的SpringMVC。
本文的相關源碼請參考:chapter-5-springmvc-zero-configuration
https://gitee.com/leo825/spring-framework-learning-example.git
2、搭建過程
2.1 開發環境搭建
開發環境搭建省略了,如果不清楚的可以參考《SpringMVC學習(一)——快速搭建SpringMVC開發環境(非注解方式)》這個里面的開發環境
2.2 項目搭建
2.2.1 首先看web.xml配置
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"version="3.1"><!-- WEB應用的名字 --><display-name>springmvc</display-name><!-- WEB應用的描述 --><description>SpringMVC的demo</description><!-- 歡迎頁面,首頁 --><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list> </web-app>這里面沒有少東西,我們本次不需要添加Spring的任何配置,因此也不需要之前Spring的applicationContext.xml和myspringmvc-servlet.xml配置文件。
2.2.2 增加WebApplicationInitializer的實現類
這個實現類似web.xml配合,注冊bean并自啟動DispatcherServlet。
public class MyWebApplicationInitializer implements WebApplicationInitializer {@Overridepublic void onStartup(ServletContext container) {//創建一個Spring應用的root上下文AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();applicationContext.register(ApplicationContextConfig.class);System.out.println("ApplicationContextConfig注冊完畢");//監聽root上下文的生命周期container.addListener(new ContextLoaderListener(applicationContext));//web上下文配置AnnotationConfigWebApplicationContext webApplicationContext = new AnnotationConfigWebApplicationContext();webApplicationContext.register(WebSpringMVCServletConfig.class);System.out.println("WebSpringMVCServletConfig注冊完畢");//創建并注冊DispatcherServletServletRegistration.Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet(webApplicationContext));registration.setLoadOnStartup(1);//設置啟動順序同等:registration.addMapping("/");System.out.println("DispatcherServlet注冊完畢");} }2.2.3 增加ApplicationContextConfig配置類
注冊bean配置類,類似我們的applicationContext.xml文件
@Configuration @ScanIgnore public class ApplicationContextConfig extends WebMvcConfigurationSupport {/*** 加載配置文件,類似之前配置文件中的:* <bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> * <property name="locations"> * <list> * <value>classpath:*.properties</value> * </list>* <property/>* </bean> * <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">* <property name="properties" ref="configProperties"/>* </bean>** @return*/@Bean(name = "configProperties")public PropertiesFactoryBean propertiesFactoryBean(){PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();propertiesFactoryBean.setLocation(new ClassPathResource("application.properties"));propertiesFactoryBean.setSingleton(true);System.out.println("propertiesFactoryBean注冊完畢");return propertiesFactoryBean;}@Bean(name = "propertyConfiguer")public MyPropertyPlaceholder preferencesPlaceholderConfigurer(PropertiesFactoryBean configProperties) throws IOException {MyPropertyPlaceholder propertyConfiguer = new MyPropertyPlaceholder();propertyConfiguer.setProperties(configProperties.getObject());System.out.println("preferencesPlaceholderConfigurer注冊完畢");return propertyConfiguer;}/*** 創建jdbcTemplate* @return*/@Bean(name = "jdbcTemplate")//只要使用name = "driverManagerDataSource"就可以將注冊的bean依賴過來public JdbcTemplate jdbcTemplate(DriverManagerDataSource driverManagerDataSource) {JdbcTemplate jdbcTemplate = new JdbcTemplate();jdbcTemplate.setDataSource(driverManagerDataSource);System.out.println("jdbcTemplate注冊完畢");return jdbcTemplate;}/*** 創建數據源* @return*/@Bean(name = "driverManagerDataSource")public DriverManagerDataSource driverManagerDataSource(MyPropertyPlaceholder propertyConfiguer) {DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();driverManagerDataSource.setDriverClassName(MyPropertyPlaceholder.getProperty("datesource.driverClassName"));driverManagerDataSource.setUrl(MyPropertyPlaceholder.getProperty("datesource.url"));driverManagerDataSource.setUsername(MyPropertyPlaceholder.getProperty("datesource.username"));driverManagerDataSource.setPassword(MyPropertyPlaceholder.getProperty("datesource.password"));System.out.println("driverManagerDataSource注冊完畢");return driverManagerDataSource;} }如果一個bean依賴其他的bean則可以按照如下方式處理
2.2.4 增加application.properties配置文件
因為2.2.3中我們使用了propertiesFactoryBean通過配置文件來獲取配置的參數,因此這里我們需要添加application.properties文件。
datesource.driverClassName=com.mysql.jdbc.Driver datesource.url=jdbc:mysql://localhost:3306/springframework_learning datesource.username=cm9vdA== datesource.password=cm9vdA==細心的同學會發現,這里的數據庫datesource.username(用戶名)和datesource.password(密碼)都是加過密的。我們正常的工作中也是會遇到用戶名密碼不能明文,但是實際連接的時候需要的是明文的情況,這就使用到了PreferencesPlaceholderConfigurer來實現配置屬性的解密操作。參考如下實現:
public class MyPropertyPlaceholder extends PreferencesPlaceholderConfigurer {//定義一個屬性的map對象private final static Map<String, String> propertyMap = new HashMap();/*** 這里要特別留意下,可以使用這種方式實現配置文件加解密,最常見的是對數據庫的配置的加解密** @param beanFactoryToProcess* @param props* @throws BeansException*/@Overrideprotected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props) throws BeansException {super.processProperties(beanFactoryToProcess, props);for (Object keyString : props.keySet()) {String key = keyString.toString();String value = props.getProperty(key);//此處是做了配置文件的解密處理,以防止配置文件明文引起安全問題if("datesource.username".equals(key) || "datesource.password".equals(key)){try {value = Base64Util.decodeDate(value);} catch (Exception e) {e.printStackTrace();value = "";}}propertyMap.put(key, value);}}//自定義一個方法,即根據key拿屬性值,方便java代碼中取屬性值public static String getProperty(String name) {return propertyMap.get(name);} }注冊bean的時候使用我們自定義的MyPropertyPlaceholder 就是解密后的配置參數了。
2.2.5 增加WebSpringMVCServletConfig配置類
Web配置類,類似以前的myspringmvc-servlet.xml,這里使用了@ComponentScan來掃描需要包,同時排除不需要掃描的包,如果不排除則會重復創建bean對象。《如何使用@component-scan排除不需要的類》 這篇文件介紹了如何排除不需要掃描的類。
@Configuration @ScanIgnore //@ComponentScan(basePackages = {"com.leo"}, excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {ApplicationContextConfig.class, WebSpringMVCServletConfig.class})) //@ComponentScan(basePackages = {"com.leo"}, excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = ScanIgnore.class)) //@ComponentScan(basePackages = {"com.leo"}, excludeFilters = @ComponentScan.Filter(type = FilterType.CUSTOM, classes = MyTypeFilter.class)) @ComponentScan(basePackages = {"com.leo"}, excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "com.leo.config.*")) public class WebSpringMVCServletConfig extends WebMvcConfigurationSupport {@Beanpublic ViewResolver viewResolver() {InternalResourceViewResolver resolver = new InternalResourceViewResolver();resolver.setPrefix("WEB-INF/views/");resolver.setSuffix(".jsp");return resolver;} }2.3 測試結果
其實到上面一步環境已經搭建完成了,下面就是寫測試類進行。
2.3.1 增加UserInfoService以及實現類UserInfoServiceImpl
UserInfoService.java如下
public interface UserInfoService {/*** 增加用戶信息* @param userInfo*/void insertUserInfo(UserInfo userInfo);/*** 刪除用戶信息* @param id*/void deleteUserInfo(Integer id);/*** 修改用戶信息* @param id 舊用戶信息的id* @param newUserInfo*/void updateUserInfo(Integer id, UserInfo newUserInfo);/*** 查詢用戶信息* @return*/List<UserInfo> getUserInfoList(); }UserInfoServiceImpl.java如下
@Service public class UserInfoServiceImpl implements UserInfoService {@AutowiredJdbcTemplate jdbcTemplate;@Overridepublic void insertUserInfo(UserInfo userInfo) {jdbcTemplate.execute("INSERT INTO USER_INFO(NAME,GENDER,AGE,REMARKS) VALUES('" + userInfo.getName() + "','" + userInfo.getGender() + "','" + userInfo.getAge() + "','" + userInfo.getRemarks() + "')");}@Overridepublic void deleteUserInfo(Integer id) {jdbcTemplate.execute("DELETE FROM USER_INFO WHERE ID = " + id);}@Overridepublic void updateUserInfo(Integer id, UserInfo newUserInfo) {jdbcTemplate.update("UPDATE USER_INFO SET NAME=?, GENDER=?, AGE=? ,REMARKS=? WHERE ID=?", new Object[]{newUserInfo.getName(),newUserInfo.getGender(),newUserInfo.getAge(),newUserInfo.getRemarks(),id});}@Overridepublic List<UserInfo> getUserInfoList() {List<UserInfo> userInfos = new ArrayList<>();List<Map<String, Object>> results = jdbcTemplate.queryForList("SELECT * FROM USER_INFO");for (Map obj : results) {UserInfo userInfo = new UserInfo();userInfo.setId((Integer) obj.get("ID"));userInfo.setName((String) obj.get("NAME"));userInfo.setGender("0".equals((String) obj.get("GENDER")) ? "女" : "男");userInfo.setAge((String) obj.get("AGE"));userInfo.setRemarks((String) obj.get("REMARKS"));userInfos.add(userInfo);}return userInfos;} }UserInfo.java如下
public class UserInfo {/*** 用戶id*/Integer id;/*** 用戶名稱*/String name;/*** 用戶性別*/String gender;/*** 用戶年齡*/String age;/*** 備注*/String remarks;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public String getRemarks() {return remarks;}public void setRemarks(String remarks) {this.remarks = remarks;}@Overridepublic String toString() {return "UserInfo{" +"id=" + id +", name='" + name + '\'' +", gender='" + gender + '\'' +", age='" + age + '\'' +", remarks='" + remarks + '\'' +'}';} }2.3.2 增加HelloWorldController
新增一個controller類,用接口測試實現
HelloWorldController.java如下
2.3.3 啟動tomcat進行測試
1.首先訪問http://localhost:8080/springmvc/helloworld
前端頁面跳轉到了success.jsp
2.然后訪問http://localhost:8080/springmvc/getUserInfoList
其中有個小插曲,訪問帶有數據的返回的時候前端頁面顯示亂碼可以使用produces = "application/json; charset=utf-8"這個屬性來處理
3、總結
至此,以上已經完成了零配置實現的SpringMVC。至于為什么能使用WebApplicationInitializer來實現類似于web.xml的配置,另一篇文章《Spring中對于WebApplicationInitializer的理解》會解釋。
總結
以上是生活随笔為你收集整理的SpringMVC学习(五)——零配置实现SpringMVC的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何使用@component-scan排
- 下一篇: Spring中对于WebApplicat