參考文章:Spring MVC 3 深刻總結;css
第二章 Spring MVC入門 —— 跟開濤學SpringMVC html
參考博客:http://www.cnblogs.com/liukemng/category/578644.htmljava
controller層配置文件介紹:mysql
一.springmvc 配置;linux
具體原理參考文章: Spring MVC 3 深刻總結web
web.xml配置文件以下:redis
<!-- Spring MVC 控制器 --> <servlet> <servlet-name>SpringDispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <!-- spring mvc 配置文件的路徑 --> <param-value>/WEB-INF/spring/servlet-context.xml</param-value> </init-param> <!-- 是啓動順序,讓這個Servlet隨Servletp容器一塊兒啓動 --> <load-on-startup>1</load-on-startup> </servlet> <!-- Spring MVC 映射配置攔截器 --> <servlet-mapping> <servlet-name>SpringDispatcherServlet</servlet-name> <!-- 攔截/,例如:/user/add,弊端:對jpg,js,css靜態文件的訪問也被攔截,靜態文件需另寫攔截器,且放在該攔截器前面 --> <url-pattern>/</url-pattern> </servlet-mapping>
其中<param-value>**.xml</param-value> 這裏可使用多種寫法
一、不寫,使用默認值:/WEB-INF/<servlet-name>-servlet.xml
二、<param-value>/WEB-INF/classes/spring/servlet-context.xml</param-value>
三、<param-value>classpath*:/spring/servlet-context.xml</param-value>
四、多個值用逗號分隔spring
Spring MVC 映射配置攔截器 沒法訪問靜態的文件,如jpg,js,css等,主要採用:激活Tomcat的defaultServlet來處理靜態文件的方法;其中 Tomcat, Jetty, JBoss, and GlassFish 默認 Servlet的名字 -- "default"sql
所以靜態文件的攔截器,要寫在DispatcherServlet的前面, 讓 defaultServlet先攔截,這個就不會進入Spring了,性能最佳;mongodb
在web.xml中加配置以下:
<!-- Spring MVC 控制器 --> <servlet> <servlet-name>SpringDispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <!-- spring mvc 配置文件的路徑 --> <param-value>/WEB-INF/spring/servlet-context.xml</param-value> </init-param> <!-- 是啓動順序,讓這個Servlet隨Servletp容器一塊兒啓動 --> <load-on-startup>1</load-on-startup> </servlet> <!-- Spring MVC 映射配置攔截器 --> <servlet-mapping> <servlet-name>SpringDispatcherServlet</servlet-name> <!-- 攔截/,例如:/user/add,弊端:對jpg,js,css靜態文件的訪問也被攔截,靜態文件需另寫攔截器,且放在該攔截器前面 --> <url-pattern>/</url-pattern> </servlet-mapping>
其中springmvc配置文件:servlet-context.xml主要內容以下:
<!-- 掃描控制層所在的包中的類上的註解 --> <context:component-scan base-package="com.springmvc.controller.**" /> <!-- 默認的註解映射的支持 :會自動註冊DefaultAnnotationHandlerMapping與AnnotationMethodHandlerAdapter 兩個bean--> <mvc:annotation-driven /> <!-- 對靜態資源文件的訪問--> <mvc:default-servlet-handler/> <!-- 攔截器 --> <mvc:interceptors> <!-- 對應代碼中攔截器類 --> <bean class="com.springmvc.common.controller.AuthenticationInerceptor"> <!-- 對應代碼中攔截器類 中屬性--> <property name="fileUri" value="${file_uri}"></property> </bean> </mvc:interceptors> <!-- 視圖解釋類 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/" /> <property name="suffix" value=".jsp" /> <property name="order" value="2" /> </bean>
解釋以下:
1.<context:component-scan/> 掃描指定的包中的類上的註解,經常使用的註解有:
@Controller 聲明Action組件
@Service 聲明Service組件 @Service("myMovieLister")
@Repository 聲明Dao組件
@Component 泛指組件, 當很差歸類時.
@RequestMapping("/menu") 請求映射
@Resource 用於注入,( j2ee提供的 ) 默認按名稱裝配,@Resource(name="beanName")
@Autowired 用於注入,(srping提供的) 默認按類型裝配
@Transactional( rollbackFor={Exception.class}) 事務管理
@ResponseBody
@Scope("prototype") 設定bean的做用域
2.<mvc:annotation-driven /> 是一種簡寫形式,徹底能夠手動配置替代這種簡寫形式,簡寫形式可讓初學都快速應用默認配置方案。<mvc:annotation-driven /> 會自動註冊DefaultAnnotationHandlerMapping與AnnotationMethodHandlerAdapter 兩個bean,是spring MVC爲@Controllers分發請求所必須的。並提供了:數據綁定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,讀寫XML的支持(JAXB),讀寫JSON的支持(Jackson)
3.<mvc:interceptors/>攔截器
4.<mvc:default-servlet-handler/> 使用默認的Servlet來響應靜態文件
二.加入攔截器;
在servlet-context.xml中加攔截器配置文件
<!-- 攔截器 --> <mvc:interceptors> <!-- 對應代碼中攔截器類 --> <bean class="com.springmvc.common.controller.AuthenticationInerceptor"> <!-- 對應代碼中攔截器類 中屬性--> <property name="fileUri" value="${file_uri}"></property> </bean> </mvc:interceptors>
具體攔截器類內容見文件:com.springmvc.common.controller.AuthenticationInerceptor
攔截器原理以及參考文章見:SpringMVC中使用Interceptor攔截器
三.加入spring 業務層+加入mybatis
1.在上下文配置文件applicationContext.xml中,加入spring封裝業務層的配置文件;
<!--加spring 業務層配置:把spring-service.xml放在controller層 --> <!--<import resource="spring/spring-service.xml" /> --> <!--加spring 業務層配置:若是按業務分類有多個service層時把spring-service-s1.xml放在各類service層 --> <import resource="classpath*:spring/spring-service-*.xml"/>
2.spring封裝業務層配置文件以下:
<!-- 基礎服務層包 --> <context:component-scan base-package="com.springmvc.service" /> <!-- 基礎dao包 --> <context:component-scan base-package="com.springmvc.dao" /> <!-- redis包 --> <context:component-scan base-package="com.springmvc.redis" /> <!-- Spring應用上下文持有器 --> <bean class="com.springmvc.common.util.SpringContextHolder"></bean> <!-- 加載配置文件,該配置文件中 有線程池的配置信息:threadpool.coreSize和 threadpool.maxSize--> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="order" value="2" /> <property name="ignoreUnresolvablePlaceholders" value="true" /> <property name="locations"> <list> <value>classpath:config.properties</value> </list> </property> </bean> <!-- 線程池的配置 --> <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <property name="corePoolSize" value="${threadpool.coreSize}" /> <property name="keepAliveSeconds" value="200" /> <property name="maxPoolSize" value="${threadpool.maxSize}" /> </bean> <!-- 業務層的事務配置文件 --> <import resource="classpath*:spring/spring-pms-transaction.xml"/> <!-- 業務層的redis緩存配置文件 --> <import resource="classpath*:spring/spring-pms-redis.xml"/> <!-- 加載各服務層的配置文件 --> <import resource="classpath*:spring/service-*.xml"/>
解釋以下:
<context:component-scan/>掃描該serivce層須要引用的全部:dao層,redis層
這裏沒有掃描model層,是由於在mybatis的配置裏,指定model層,和對應mapper.xml的位置;
<bean class="com.springmvc.common.util.SpringContextHolder" /> spring上下文持有器,能夠在該層取到:ApplicaitonContext,這樣能夠取得spring管理的bean;
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 讀取.property配置文件,必須的,能夠設置多個;
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> 多線程,線程池的配置
具體的實現可參考:使用SPRING中的線程池ThreadPoolTaskExecutor實現JAVA併發
<import resource="classpath*:spring/spring-pms-transaction.xml"/> 引入其餘層的配置文件
注意:classpath*:與classpath:的區別:classpath:只會到你的class路徑中查找找文件; classpath*:不只包含class路徑,還包括jar文件中(class路徑)進行查找.
具體的參考:web.xml 配置中classpath: 與classpath*:的區別
3.加入mybatis,事務處理配置文件spring-transaction.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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd"> <!-- 加載jdbc配置文件 --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="order" value="1" /> <property name="ignoreUnresolvablePlaceholders" value="true" /> <property name="locations"> <list> <value>classpath:jdbc.properties</value> </list> </property> </bean> <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="initialSize" value="${jdbc.initialPoolSize}" /> <property name="maxActive" value="${jdbc.maxPoolSize}" /> <property name="maxIdle" value="${jdbc.maxIdle}" /> <property name="maxWait" value="3000"/> <property name="testWhileIdle" value="true" /> <property name="testOnBorrow" value="false" /> <property name="testOnReturn" value="false" /> <property name="validationQuery" value="${jdbc.validationQuery}" /> <property name="timeBetweenEvictionRunsMillis" value="${dbcp.timeBetweenEvictionRunsMillis}" /> <property name="numTestsPerEvictionRun" value="${dbcp.numTestsPerEvictionRun}" /> <property name="removeAbandoned" value="true" /> <property name="removeAbandonedTimeout" value="180"/> <property name="minEvictableIdleTimeMillis" value="${dbcp.minEvictableIdleTimeMillis}" /> </bean> <!-- MyBatis數據庫標識提供者,能夠在select/update/delete/insert加上databaseId的方式來標識不一樣的數據庫,也能夠直接使用屬性<if test="_databaseId == 'mysql'">來判斷不一樣的數據庫 --> <bean id="databaseIdProvider" class="org.apache.ibatis.mapping.VendorDatabaseIdProvider"> <property name="properties"> <props> <prop key="Oracle">oracle</prop> <prop key="MySQL">mysql</prop> <prop key="Microsoft SQL Server">sqlserver</prop> <prop key="DB2">db2</prop> </props> </property> </bean> <!-- MyBatis配置 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="classpath:mybatis/mybatis-config.xml" /> <property name="mapperLocations" value="classpath*:mybatis/**/*Mapper.xml" /> <property name="databaseIdProvider" ref="databaseIdProvider"/> <property name="typeAliasesPackage" value="com.springmvc.entity"/> <property name="plugins" > <bean class="com.springmvc.common.mybatis.PaginationInterceptor"> <property name="properties"> <props> <prop key="dialect">${jdbc.dialect}</prop> </props> </property> </bean> </property> </bean> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref="sqlSessionFactory" /> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <aop:config> <aop:pointcut id="serviceMethod" expression="execution(* com.springmvc.*.service..*.*(..))" /> <aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice" /> <!-- 也能夠下面這樣配置--> <!-- <aop:pointcut id="baseServiceMethod" expression="execution(* com.cdc.common.service..*.*(..))" /> <aop:pointcut id="serviceMethod" expression="execution(* com.cdc.service..*.*(..))" /> <aop:advisor pointcut-ref="baseServiceMethod" advice-ref="txAdvice" /> <aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice" /> --> </aop:config> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="get*" read-only="true" /> <tx:method name="query*" read-only="true" /> <tx:method name="select*" read-only="true" /> <tx:method name="save*" propagation="REQUIRED"/> <tx:method name="insert*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="add*" propagation="REQUIRED"/> <tx:method name="process*" propagation="REQUIRED"/> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <tx:annotation-driven transaction-manager="transactionManager" /> </beans>
public AbstractDAO() { @SuppressWarnings("rawtypes") Class c = getClass(); Type type = c.getGenericSuperclass(); if (type instanceof ParameterizedType) { Type[] parameterizedType = ((ParameterizedType) type) .getActualTypeArguments(); this.entityClass = (Class<T>) parameterizedType[0]; nameSpace = entityClass.getCanonicalName(); } }
四.加入redis;
對應包:jedis-2.0.0.jar,在service層調用redis,這個後續補充
<?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:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="com.springmvc.redis" /> <!-- 加載配置文件 --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="order" value="2" /> <property name="ignoreUnresolvablePlaceholders" value="true" /> <property name="locations"> <list> <value>classpath:redis.properties</value> </list> </property> </bean> <!-- POOL配置 --> <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxActive" value="${redis.maxActive}" /> <property name="maxIdle" value="${redis.maxIdle}" /> <property name="maxWait" value="${redis.maxWait}" /> <property name="testOnBorrow" value="false" /> </bean> <!-- jedis shard信息配置 --> <bean id="jedisShardInfo" class="redis.clients.jedis.JedisShardInfo"> <constructor-arg index="0" value="${redis.host}" /> <!-- host --> <constructor-arg index="1" value="${redis.port}" /> <!-- port --> <constructor-arg index="2" value="${redis.timeout}" /> <!-- timeout --> </bean> <!-- redis 鏈接池配置 --> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" > <property name="usePool" value="true"/> <property name="poolConfig" ref="jedisPoolConfig"/> <property name="shardInfo" ref="jedisShardInfo"/> </bean> <!-- redis template --> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="jedisConnectionFactory"/> <property name="keySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean> </property> <property name="valueSerializer"> <bean class="com.springmvc.common.redis.Object2StringRedisSerializer"></bean> </property> <property name="hashKeySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"></bean> </property> <property name="hashValueSerializer"> <bean class="com.springmvc.common.redis.Object2StringRedisSerializer"></bean> </property> </bean> </beans>
四.加入spring-security;
參考文章:Spring安全權限管理(Spring Security的配置使用)
原理:Spring Security 3 基於角色訪問控制過程詳解
主要引用jar包:spring-security-cas-3.1.4.RELEASE.jar;
spring-security-config-3.1.4.RELEASE.jar;
spring-security-core-3.1.4.RELEASE.jar;
spring-security-crypto-3.1.4.RELEASE.jar;
spring-security-taglibs-3.1.4.RELEASE.jar;
spring-security-web-3.1.4.RELEASE.jar;
1.在上下文文件:applicationContext.xml 中加入配置:
<!-- 掃描spring security相關類相關文件的路徑 --> <context:component-scan base-package="com.springmvc.security" /> <!-- 加spring security 配置文件 --> <import resource="spring/spring-security.xml" />
2.在web.xml中加入spring-security的過濾器和監聽器:
<!-- spring security過濾器 cjjuan --> <filter> <filter-name>springSecurityFilterChain</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> </filter> <filter-mapping> <filter-name>springSecurityFilterChain</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--Spring security配置HttpSessionEventPublisher防用戶重複登陸 cjjuan - Publishes events for session creation and destruction through the application - context. Optional unless concurrent session control is being used. --> <listener> <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class> </listener>
3.spring-security自身的配置文件:spring-security.xml的內容以下:
<?xml verssion="1.0" encoding="UTF-8"?> <beans:beans xmlns="http://www.springframework.org/schema/security" xmlns:beans="http://www.springframework.org/schema/beans" 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-3.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"> <http pattern="/css/**" security="none"/> <http pattern="/js/**" security="none"/> <http pattern="/images/**" security="none"/> <http pattern="/login.jsp*" security="none"/> <http auto-config="true" access-denied-page="/noauth.jsp"> <intercept-url pattern="/**" access="ROLE_COMPANY" /> <form-login login-page="/login.jsp" authentication-failure-url="/login.jsp?login_error=1" default-target-url="/test/list"/> <custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="customFilter" /> </http> <beans:bean id="customFilter" class="com.springmvc.security.SecurityInterceptor"> <beans:property name="authenticationManager" ref="authenticationManager"/> <beans:property name="accessDecisionManager" ref="accessDecisionManager" /> <beans:property name="securityMetadataSource" ref="customSecurityMetadataSource" /> </beans:bean> <beans:bean id="customSecurityMetadataSource" class="com.springmvc.security.SecurityMetadataSource"> </beans:bean> <beans:bean id="accessDecisionManager" class="com.springmvc.security.RoleAccessDecisionManager"> </beans:bean> <beans:bean id="userDetailServiceImpl" class="com.springmvc.security.UserDetailServiceImpl"> </beans:bean> <authentication-manager alias="authenticationManager"> <authentication-provider user-service-ref='userDetailServiceImpl'> <password-encoder hash="md5"/> </authentication-provider> </authentication-manager> </beans:beans>
spring-security.xml 中提到的實體類和引用的jar包分別以下:
五。加入freemarker
涉及到的引用包爲:freemarker-2.3.15.jar; jstl.jar
其中 freemarker 配置信息寫在freemarker.xml中,而後將該文件import到servlet-context.xml(springMVC的配置文件)中,
freemarker.xml 指定了freemarker對應html的存放路徑:
具體的見,本身寫的文檔:spring mvc中使用freemark的一點心得
六.加入freemarker裏的國際化
SpringMVC + FreeMarker 國際化使用方法
1.配置xml文件
<!-- 基於Session的國際化實現 --> <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" /> <!-- 國際化操做攔截器 若是採用基於(請求/Session/Cookie)則必需配置 --> <bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" /> <!-- 國際化資源文件存放路徑 --> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basenames"> <list> <value>/WEB-INF/message/messages</value> </list> </property> <property name="cacheSeconds" value="0" /> </bean>
注意事項:1.basenames裏的
若是資源文件名爲 test_zh_CN.properties,則該處改成:/WEB-INF/message/test
2.引入spring.ftl文件,該文件在:spring-webmvc-3.2.6.RELEASE.jar\org\springframework\web\servlet\view\freemarker\下
複製到
3.在html裏import 該spring.ftl,如上圖:testList.html中引用:
import的路徑,是以freemark設置的默認路徑爲參照,由於該freemark路徑是template,因此這裏import路徑如上圖
4.經過來java設置採用哪一種語言
//設置爲英文格式化,到messages_en.properties 文件裏去找 request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, new Locale("en")); //設置爲中文格式化,到messages_zh_CN.properties 文件裏去找 request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, new Locale("zh", "CN")); // 根據properties文件的編碼,取對應的中英文內容; String msg=HttpUtil.getMessage(request, "tab.all");
另,在代碼中根據資源文件的編碼,取對應的中英文內容: HttpUtil.getMessage(request, "tab.all");
七.封裝自定義控件;
見本身寫的 用freemarker定義宏實現自定義公用控件
調用的時候,只須要把控件的html 給 include 進去就能夠了,具體的以下圖:
八.Spring事件監聽器與異步機制
參考:spring發佈和接收定製的事件(spring事件傳播)
1.事件:TestTaskEvent 繼承 ApplicationEvent,具體的見代碼
2.監聽器:TestListener 實現接口 ApplicationListener<TestTaskEvent>,具體的見代碼
3.發佈:SpringContextHolder 實現接口 ApplicationContextAware, ServletContextAware,具體的見代碼,並確保有spring應用上下文持有器
調用代碼:
@Override public void testEvent() { // 發佈事件 System.out.println("我要發佈信息。。。。。。。。"); Map<String,Object> map=new HashMap<String,Object>(); map.put("a1", "a1"); TestTaskEvent event = new TestTaskEvent(map); SpringContextHolder.getApplicationContext().publishEvent(event); }
測試結果:
注意:不少文章裏寫的在配置文件xml中注入TestListener,這裏使用了springMVC的自動掃描
1.在配置文件中配置Event和Listener的掃描路徑;
<!-- Spring Event異步機制 --> <context:component-scan base-package="com.springmvc.event" /> <context:component-scan base-package="com.springmvc.listener" />
2.發佈,必須確保spring-service-s1.xml中有配置:
<!-- Spring應用上下文持有器 -->
<bean class="com.springmvc.common.util.SpringContextHolder"></bean>
3.在TestListener 實現類上加:@Service
九.定時器任務調度Quartz
參考文檔:SpringMVC整合Quartz實現定時任務和Spring自帶Task定時任務
框架Quart在Java中任務調度的使用
主要引用jar包:quartz-all-1.8.6.jar
Quartz核心的概念:scheduler任務調度、Job任務、Trigger觸發器、JobDetail任務細節
scheduler任務調度:觸發器工程,將全部定時任務都注入工廠;(在配置文件job-scheduler.xml中設置)
Job任務:其實Job是接口,其中只有一個execute方法,咱們開發者只要實現此接口,實現execute方法便可。把咱們想作的事情,在execute中執行便可;
(TestJob.java,配置文件job-scheduler.xml中也有指向該類)
JobDetail:任務細節,Quartz執行Job時,須要新建個Job實例,可是不能直接操做Job類,因此經過JobDetail來獲取Job的名稱、描述信息
(在配置文件job-scheduler.xml中設置)
Trigger觸發器:執行任務的規則;好比天天,每小時等。指定JobDetail和執行規則;(在配置文件job-scheduler.xml中設置)
配置文件job-scheduler.xml以下文
<!-- 業務service裏的包 --> <import resource="classpath*:spring/spring-service-*.xml"/> <!-- 定時任務包 --> <context:component-scan base-package="com.springmvc.quartz.job.test.**" /> <!--job執行規則時間設置文件 --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="order" value="2" /> <property name="ignoreUnresolvablePlaceholders" value="true" /> <property name="locations"> <list> <value>classpath:cron.properties</value> </list> </property> </bean> <!-- scheduler任務調度(觸發器工程,將全部定時任務都注入工廠) --> <bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <!-- 設置數據源 --> <!-- <property name="dataSource" ref="dataSource"/> --> <!-- 設置事務管理器,若是設置了數據源則必定要事務管理器 --> <!-- <property name="transactionManager" ref="transactionManager" /> --> <!-- <property name="configLocation" value="classpath:quartz.properties" /> --> <!-- 添加觸發器 --> <property name="triggers"> <list> <!--將下面配置的全部定時任務注入(要執行的Trigger都要在這裏注入) --> <ref bean="triggerTest" /> </list> </property> </bean> <!--Trigger觸發器(指定jobDetail和觸發的時間規則)--> <bean id="triggerTest" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail" ref="jobDetailTest" /> <property name="cronExpression" value="${quartz.test.minute}" /> </bean> <!-- JobDetail(任務細節) --> <bean id="jobDetailTest" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject"> <ref bean="jobTest"/> </property> <property name="targetMethod"> <value>execute</value> </property> <!-- 設置是否同步 false的話會等第一個job執行完纔會執行後面的 --> <property name="concurrent"> <value>false</value> </property> </bean> <!-- Job(任務),指向具體的job類 --> <bean id="jobTest" class="com.springmvc.quartz.job.test.TestJob"> </bean>
其中測試調用代碼以下:選中該文件中的函數main,右鍵彈框--> Run As --> java application 進行測試
public class ServerMain { public static void main(String[] args) { RPCServer server = new RPCServer("spring/job-scheduler.xml"); server.start(); } }
運行結果以下:
17:10:00,002 INFO [TestJob] springmvc-test:數據定時器,啓動。。。。
17:10:00,002 INFO [TestJob] springmvc-test:數據定時器:print users.開始。。。。
34009677
34009721
34009635
34009633
17:10:00,075 INFO [TestJob] springmvc-test:數據定時器:print users.結束。。。。
17:10:00,075 INFO [TestJob] springmvc-test:數據定時器,結束。。。。
添加packing-build.xml文件,指定打包內容
<?xml version="1.0" encoding="UTF-8"?> <!-- project元素 name project名字,default 默認執行的target --> <project name="SpringMVC_Quartz" default="dir"> <!--發佈到的路徑 --> <property name="publish.dir" value="D:/PM/SpringMVC_Quartz"/> <target name="dir" description="folder"> <!-- 複製應用 --> <copy todir="${publish.dir}/classes" includeEmptyDirs="false" overwrite="true"> <fileset dir="bin" excludes="mock/*.class"/> </copy> <!-- 複製execute --> <copy todir="${publish.dir}/execute" includeEmptyDirs="true" overwrite="true"> <fileset dir="execute"/> </copy> <!-- 複製lib包,全部引用的jar包 --> <copy todir="${publish.dir}/lib" overwrite="true"> <!-- lib --> <fileset dir="../SpringMVC_Common/lib"/> </copy> <!--引用其餘工程,須要把其餘工程生成的包,複製到該工程的lib下 --> <!-- 複製SpringMVC_Common工程 --> <copy todir="${publish.dir}/temp/SpringMVC_Common" overwrite="true"> <fileset dir="../SpringMVC_Common/bin"/> </copy> <jar destfile ="${publish.dir}/lib/SpringMVC_Common.jar" basedir ="${publish.dir}/temp/SpringMVC_Common" /> <!-- 複製SpringMVC_DAO工程 --> <copy todir="${publish.dir}/temp/SpringMVC_DAO" overwrite="true"> <fileset dir="../SpringMVC_DAO/bin"/> </copy> <jar destfile ="${publish.dir}/lib/SpringMVC_DAO.jar" basedir ="${publish.dir}/temp/SpringMVC_DAO" /> <!-- 複製SpringMVC_Model工程 --> <copy todir="${publish.dir}/temp/SpringMVC_Model" overwrite="true"> <fileset dir="../SpringMVC_Model/bin"/> </copy> <jar destfile ="${publish.dir}/lib/SpringMVC_Model.jar" basedir ="${publish.dir}/temp/SpringMVC_Model" /> <!-- 複製SpringMVC_Redis工程 --> <copy todir="${publish.dir}/temp/SpringMVC_Redis" includeEmptyDirs="false" overwrite="true"> <fileset dir="../SpringMVC_Redis/bin" excludes="redis.properties"/> </copy> <copy file="../SpringMVC_Redis/bin/redis.properties" tofile="${publish.dir}/temp/SpringMVC_Redis/redis.properties" overwrite="true" /> <jar destfile ="${publish.dir}/lib/SpringMVC_Redis.jar" basedir ="${publish.dir}/temp/SpringMVC_Redis" /> <!-- 複製SpringMVC_Service工程 --> <copy todir="${publish.dir}/temp/SpringMVC_Service" includeEmptyDirs="false" overwrite="true"> <fileset dir="../SpringMVC_Service/bin" excludes="config.properties,jdbc.properties"/> </copy> <copy file="../SpringMVC_Service/bin/config.properties" tofile="${publish.dir}/temp/SpringMVC_Service/config.properties" overwrite="true" /> <copy file="../SpringMVC_Service/bin/jdbc.properties" tofile="${publish.dir}/temp/SpringMVC_Service/jdbc.properties" overwrite="true" /> <jar destfile ="${publish.dir}/lib/SpringMVC_Service.jar" basedir ="${publish.dir}/temp/SpringMVC_Service" /> <delete dir="${publish.dir}/temp"/> </target> </project>
在execute文件夾下,加start.bat文件;修改該文件,指向測試用的 ServerMain文件
用Ant發佈:windows--> show view -->Ant,彈出小螞蟻窗口。在Ant窗口中,右鍵--> add BuildFiles...選中該項目的packing-build.xml後,以下:
選中該項目,右鍵 --->Run As --->Ant Build,則將該工程發佈到指定的路徑下:
十.日誌文件
參考文檔:基礎內容見:java日誌文件log4j.properties配置詳解 以及 Log4J日誌配置詳解
其中日誌文件的擴展類實現見:擴展log4j系列[一]爲DailyRollingFileAppender加上maxBackupIndex屬性 與咱們系統中的擴展類 :DailyMaxRollingFileAppender相對應
主要引用jar包:log4j-1.2.17.jar;
slf4j-api-1.7.5.jar ;
slf4j-log4j12-1.7.5.jar
其中日誌文件配置以下:
log4j.rootLogger=INFO,CONSOLE,FILE,useraction
#輸出到控制檯
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=DEBUG
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ABSOLUTE} %-5p [%c{1}] %m%n
#輸出到file,也就是logger的輸出
log4j.appender.FILE=org.apache.log4j.DailyMaxRollingFileAppender
log4j.appender.FILE.threshold=DEBUG
log4j.appender.FILE.DatePattern='.'yyyy-MM-dd
log4j.appender.FILE.maxBackupIndex=10
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%d - %-5p %C.%M(%F:%L) - %m%n
#日誌文件後追加,以避免覆蓋原來的文件
log4j.appender.FILE.append=true
log4j.appender.FILE.file=${catalina.home}/logs/springmvc_test.log
log4j.appender.FILE.bufferedIO=false
#輸出到useraction,用戶操做日誌,以loggerUserAction輸出到另外一個文件中
log4j.logger.useraction= DEBUG, useractionfile
log4j.additivity.useraction = false
log4j.appender.useractionfile=org.apache.log4j.DailyMaxRollingFileAppender
log4j.appender.useractionfile.threshold=DEBUG
log4j.appender.useractionfile.DatePattern='.'yyyy-MM-dd
log4j.appender.useractionfile.maxBackupIndex=10
log4j.appender.useractionfile.layout=org.apache.log4j.PatternLayout
log4j.appender.useractionfile.layout.ConversionPattern=%d - %-5p %C.%M(%F:%L) - %m%n
log4j.appender.useractionfile.append=true
log4j.appender.useractionfile.file=${catalina.home}/logs/springmvc_action.log
log4j.appender.useractionfile.bufferedIO=false
#com.springmvc架包下設置爲debug
log4j.category.com.springmvc = DEBUG
log4j.category.java.sql = DEBUG
其中java代碼調用:
//應用系統的日誌 protected final Log logger = LogFactory.getLog(getClass()); //用戶操做日誌 protected final Log loggerUserAction = LogFactory.getLog("useraction"); logger.info("write to file springmvc_test.log"); loggerUserAction.info("write to file springmvc_userAction.log");
結果以下:
十一.搜索引擎solar(solr4.9.1版本,對應jdk爲1.7)
1.solr的啓動以及配置:
cmd-->d:\platform\solr-4.9.1\example\下 啓動 Jetty下的solr,命令:「java -jar start.jar」,啓動後,在瀏覽器中輸入http://localhost:8983/solr/則進入solr的管理頁面
以下圖:
參考:Lucene/Solr搜索引擎開發筆記 - 第1章 Solr安裝與部署(Jetty篇)
2.在solr管理頁面中,增,刪,查數據:
在linux系統上直接使用post命令就能夠完成數據導入。
在windows上咱們必需要使用solr-4.9.1\example\exampledocs下的post.jar來完成數據導入(同時在這裏也能夠看到一些測試數據,如sd500.xml),先cd到exampledocs目錄,而後輸入"java -jar post.jar -h"來獲取post.jar的使用幫助:
先導入一個xml數據文件試試:"java -Dc=collection1 -jar post.jar sd500.xml" (這裏的紅色字體,與上圖中的1對應)
查詢如上圖1,2,3便可,在3中輸入內容,刪除見參考文檔。 參考文檔:全文檢索引擎Solr系列——入門篇
3.在Tomcat中整合solr,整合後,以下圖:
參考文檔: Lucene/Solr搜索引擎開發筆記 - 第2章 Solr安裝與部署(Tomcat篇)
4.與java代碼的整合 :java整合solr5.0之solrj的使用
十二.RPC實現及其接口(Provider角色)
引入.jar包:dubbo-2.5.3.jar;
netty-3.2.7.Final.jar;
zkclient-0.2.dev.jar; javassist-3.17.1-GA.jar;
zookeeper-3.4.4.jar; RPC工程佈局以下:
在工程SpringMVC_RPC.API中放對外公開的接口:com.springmvc.rpc.api,以及接口返回字段的接收對象com.springmvc.rpc.model 以方便其餘工程調用;若是其餘工程想調用該RPC只須要引用該接口工程便可;
在工程SpringMVC_RPC.Impl 用於接口的實現,這裏包括service,dao,mapper.xml以及相關的配置文件;其中service層到mapper.xml的配置若有問題,
參考:三.加入spring 業務層+加入mybatis;其中主要要注意的是spring-transaction.xml中mybatis的配置注意:
其中dubbo應用RPC提供方的配置文件以下:
<?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.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd "> <!-- 定義提供方應用信息,用於計算依賴關係 --> <dubbo:application name="rpcApi" /> <!-- 指定zookeeper服務 --> <dubbo:registry address="zookeeper://127.0.0.1:2088" /> <!-- 用dubbo協議在20880端口暴露服務 --> <dubbo:protocol name="dubbo" port="2066" host="127.0.0.1" /> <!-- 定義聲明須要暴露的服務接口:如代碼中的接口 ITestApi,並指定接口實現TestApiImpl--> <dubbo:service interface="com.springmvc.rpc.api.ITestApi" ref="testApi"/> <bean id="testApi" class="com.springmvc.rpc.impl.TestApiImpl" /> </beans>
RPC應用調用方的配置文件以下:
<?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.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- check:爲true表示啓動時,驗證 testApi接口是否存在 --> <dubbo:reference id="testApi" interface="com.springmvc.rpc.api.ITestApi" check="false"/> </beans>
注:dubbo-rpc.xml文件放在接口工程中,RPC自己的啓動,不會讀取該文件,主要是提供給調用方,也就是consumer使用,下文在portal中調用RPC接口;
接口實現端單元測試:
@ContextConfiguration(locations = { "classpath:spring/spring-rpc.xml" }) public class TestApi extends AbstractJUnit4SpringContextTests{ @Autowired ITestApi testApi; @Test public void getByUsername() throws ParseException { RPCUsers rpcUser= testApi.getByUsername("34004198"); System.out.println("rpcUser="+JacksonMapper.toString(rpcUser)); } }
十三.web中調用RPC接口服務(Comsumer角色)
在SpringMVC_Controller中調用RPC服務
1.controller工程中引用接口工程:SpringMVC_RPC.API
2.指定對應的zookeeper以及掃描相應接口端提供的dubbo-rpc.xml文件
在spring的上下文配置文件中引用接口配置文件,在applicationContext.xml中加如下內容
3.在dubbo-consumer-api.xml中配置調用RPC,好比dubbo_consumer的定義,指定的zookeeper,以及調用的接口testAPI等,具體見配置文件
<?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.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd"> <!-- dubbo調用方 --> <dubbo:application name="RPC_dubbo_Consumer"/> <!-- zookeeper的指定 --> <dubbo:registry address="zookeeper://192.168.1.156:2088" /> <!-- 掃描各API下的consumer 配置文件,如SpringMVC_RPC.API 下的dubbo-rpc.xml等 --> <import resource="classpath*:spring/dubbo-*.xml"/> </beans>
其中,<import resource="classpath*:spring/dubbo-*.xml"/> 能掃描到SpringMVC_RPC.API中的spring/dubbo-rpc.xml
4.java代碼的調用:
@Autowired @Qualifier("testApi") ITestApi testApi; /** * 測試RPC及其接口 * @param request * @param response * @param map * @return */ @RequestMapping(value = "/testApi") @ResponseBody public ModelAndView testApi(HttpServletRequest request, HttpServletResponse response, ModelMap map){ map.put("controllerUri", "http://127.0.0.1:8080/springmvc"); RPCUsers u= testApi.getByUsername("34004198"); map.put("searchText", "測試RPC及其接口:"+JacksonMapper.toString(u)); return new ModelAndView("/test/testList", map); }
其中:ITestApi 和 RPCUsers都是 SpringMVC_RPC.API中的類
結果以下:
若是要修改start.bat黑屏的標題,在start.bat中 @echo off 下添加: title 組織架構_RPC_端口21880
有時候發佈成功,可是在windows下執行start.bat文件後,若是報錯,黑屏會一閃而過,關閉掉。
爲了方便調試,能夠在cmd裏啓動start.bat,這樣黑屏就不會關閉。eg:packing-build.xml生成的文件在:D:\Amq\execute\start.bat
十四。zookeeper+dubbo
參考文檔:Dubbo與Zookeeper、SpringMVC整合和使用(負載均衡、容錯)
1. 設置啓動zookeeper:在zookeeper-3.4.4/conf/zoo.cfg中 配置 zookeeper的端口:clientPort=2088;啓動zookeeper-3.4.4/bin/zkServer.cmd 成功啓動zookeeper服務;
2.dubbo-monitor 用於監控:dubbo-monitor-simple-2.5.3-assembly 簡易監控中心安裝
3.dubbo+zookeeper與提供者、消費者之間端口通訊問題(No provider available for the service)
4.com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method 錯誤處理
十五。CAS
十六。Redis
參考:redis系列文章
在java中使用redis,則須要下載 jedis-2.0.0.jar,並加載到項目中。
十七。mongodb
參考:8天學通mongodb
十八。activity工做流