SSM framework integration
SSM framework includes spring, spring MVC and Mybatis. Spring and spring MVC are both modules of the Spring Framework and do not need to be integrated. Just integrate Mybatis with spring
1, Integration concerns
- Application of Spring in web project
When the web project starts, read ApplicationContext MXL configuration file, creating IOC container - Use connection pool as data source
Direct connection to data source or data source in Spring (DriverManagerDataSource), connection efficiency is too low. Use Alibaba's druid connection pool as the connection data source - Combination of Mybatis and Spring
Manage the proxy objects of SqlSessionFactory and mapper interfaces through the IOC container of Spring
2, Import dependency
1. Spring dependency
<!-- spring Core package--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.3.18.RELEASE</version> </dependency> <!-- springbean package --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.3.18.RELEASE</version> </dependency> <!-- springcontext package --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.18.RELEASE</version> </dependency> <!-- spring Expression package --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>4.3.18.RELEASE</version> </dependency> <!-- springAOP package --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.3.18.RELEASE</version> </dependency> <!-- springAspects package --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>4.3.18.RELEASE</version> </dependency> <!-- springJDBC package --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.3.18.RELEASE</version> </dependency> <!-- spring Transaction package --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>4.3.18.RELEASE</version> </dependency> <!-- spring yes web Support of --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.18.RELEASE</version> </dependency> <!-- springwebMVC --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>4.3.18.RELEASE</version> </dependency>
2. Mybatis dependence
<!-- mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <!-- mybatis Paging assistant for--> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.2</version> </dependency>
3. Integration and dependency of mybatis and Spring
<!--Mybatis And spring Integration package--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.2</version> </dependency>
4. Connection pool and database driver dependency
<!-- oracle drive--> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc6</artifactId> <version>11.2.0</version> </dependency> <!-- mysql drive --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <!--Connection pool: Druid data source--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version> </dependency>
5. Java Web environment dependency
<!-- servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!-- jsp-api --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> <scope>provided</scope> </dependency> <!-- jstl --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency>
6. Optional plug-in dependency
<!-- Upload component package --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> <!-- jackson --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.5</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.5</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.9.5</version> </dependency> <!-- hibernate Validation framework for--> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.4.1.Final</version> </dependency> <!-- log4j --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!-- junit--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency>
3, Directory structure
establish Java software package structure under src/main/java directory, store various configuration files and resource files under src/main/resources directory, store web project static resources and WEB-INF directory under webapp directory, and store jsp pages under web-inf
4, Configuration file
1. web.xml
1.1 character encoding filter
Use the character encoding filter provided in Spring
<!--Character encoding filter--> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
1.2 listener of IOC container
When the web project starts, after the context object ServletContext object is initialized, read the Spring configuration file and create the IOC container object, and finally put it into the context scope
Listener provided by Spring contextloader
<!-- Initialization parameters of upper and lower objects--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/applicationContext*.xml</param-value> </context-param> <!-- springIOC container--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
1.3 front end controller
<!-- Configure front-end controller--> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc/springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
1.4 welcome page
<welcome-file-list> <welcome-file>/WEB-INF/jsp/index.jsp</welcome-file> </welcome-file-list>
1.5 other configurations
<!-- It is solved by hiding domain parameters form Tabular PUT And DELETE Mode request --> <filter> <filter-name>HiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>HiddenHttpMethodFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- solve put Request to pass parameters--> <filter> <filter-name>HttpPutFormContentFilter</filter-name> <filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class> </filter> <filter-mapping> <filter-name>HttpPutFormContentFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
2. Mybatis configuration file
previously in mybatis config XML needs to load resources, global parameters, type aliases, paging plug-ins, connect to the database environment, load mapping files and other configurations. However, after integration with Spring, loading resources and connecting to the database environment must be moved into Spring for configuration. It is recommended to move the loading mapping file into Spring (wildcards can be used), and the other two can be used. If you move everything into the Spring configuration, this file can disappear
<configuration> <!-- Loading resource files: undoing--> <!-- Global parameter settings--> <!-- Custom type alias--> <typeAliases> <package name="com.ssm.entity"/> </typeAliases> <!-- Paging plug-in--> <plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <!-- Enable rationalization paging--> <property name="reasonable" value="true"/> </plugin> </plugins> <!-- Database connected environment: abolishing--> <!-- Loading mapping files: undoing--> </configuration>
3. Spring configuration file
because there are too many configurations in spring, spring can be divided into multiple files for separate configuration. On the web XML can be loaded together with wildcards (classpath:spring/applicationContext*.xml)
3.1 applicationContext.xml
- Annotation scanning
Configuration: the basic package is a public package (com.ssm), and the @ Controller annotation is filtered out
Idea: Spring and spinmvc scan their respective contents separately. Spinmvc scans the class (Controller) of the presentation layer, while Spring scans others
<context:component-scan base-package="com.ssm"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
- data source
Configuration: read dB In the properties file, the data source object adopts the Druid connection pool under Alibaba, and configures the basic information of the connection database and the key information of the connection pool
<!-- Import external resource file--> <context:property-placeholder location="classpath:db.properties"/> <!-- Configuration of data source: Druid connection pool--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <!-- Basic configuration --> <property name="driverClassName" value="${jdbc.oracle.driver}"/> <property name="url" value="${jdbc.oracle.url}"/> <property name="username" value="${jdbc.oracle.username}"/> <property name="password" value="${jdbc.oracle.password}"/> <!-- Key configuration --> <!-- The number of physical connections established during initialization. Initialization occurs in the display call init Method, or the first time getConnection Time --> <property name="initialSize" value="${druid.initialSize}" /> <!-- Minimum number of connection pools --> <property name="minIdle" value="${druid.minIdle}" /> <!-- Maximum number of connection pools --> <property name="maxActive" value="${druid.maxActive}" /> <!-- Configure the timeout time for getting connections --> <property name="maxWait" value="${druid.maxWait}" /> </bean>
- Mybatis
Configuration: SqlSessionFactory object bean and proxy object bean of mapper interface
Idea:- The best use scope of SqlSessionFactory is that it can be reused once created during the whole application operation, and is usually managed in single instance mode. Create a singleton SqlSessionFactory through the SqlSessionFactoryBean in the mybatis spring integration package
- The properties of SqlSessionFactoryBean must be configured with the data source. You can optionally load the global configuration file of mybatis (if part of the content is still in it), load the mapper mapping file (it is recommended to configure here, you can use the unified character to load in batch), type alias, plug-in and other information
- The mapper proxy object in Mybatis can be configured separately for each interface through MapperFactoryBean. Just tell Dao the fully qualified name of the interface. Disadvantages: when there are too many Dao interfaces in medium and large projects, the amount of configuration is too large, so it is not recommended to use them
- Configure mapper proxy scanner through MapperScannerConfigurer to configure mapper proxy objects in batches. You only need to tell Dao the storage package name of the interface and SqlSessionFactory
<!-- mybatis of SqlSessionFactory object--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- data source--> <property name="dataSource" ref="dataSource"/> <!-- load mybatis Global profile for--> <property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/> <!-- load mapper Mapping file,Wildcards can be used--> <property name="mapperLocations" value="classpath:mybatis/mapper/*.xml"/> </bean>
<!-- mapper Proxy object --> <bean id="empDao" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="mapperInterface" value="com.ssm.dao.EmpDao"/> </bean> <bean id="deptDao" class="org.mybatis.spring.mapper.MapperFactoryBean"> <property name="mapperInterface" value="com.ssm.dao.DeptDao"/> </bean>
<!-- mapper Scanner for proxy object--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- Scan base package--> <!-- If there are multiple base packages, you can use commas to separate them--> <property name="basePackage" value="com.ssm.dao" /> <!-- injection SqlSessionFactory--> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean>
3.2 applicationContext-tx.xml
- Transaction management profile
Configuration: transaction manager object, transaction, transaction attribute, transaction pointcut
Idea:- Transaction related configurations are placed in this file and separated from other configurations to reduce the bloated configuration file and facilitate later maintenance
- The persistence layer uses the Mybatis framework, and the transaction manager adopts the JDBC transaction manager (data source transaction manager), and injects the data source object
- The transaction attributes can be better and reasonably configured according to different needs
- Transaction pointcuts apply transactions in the specified pointcut expression through AOP
<!-- Transaction manager--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- Injection data source--> <property name="dataSource" ref="dataSource"/> </bean> <!-- affair--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- Configure transaction properties--> <tx:attributes> <tx:method name="insert*" propagation="REQUIRED" isolation="READ_COMMITTED"/> <tx:method name="save*" propagation="REQUIRED" isolation="READ_COMMITTED"/> <tx:method name="add*" propagation="REQUIRED" isolation="READ_COMMITTED"/> <tx:method name="update*" propagation="REQUIRED" isolation="READ_COMMITTED"/> <tx:method name="edit*" propagation="REQUIRED" isolation="READ_COMMITTED"/> <tx:method name="del*" propagation="REQUIRED" isolation="READ_COMMITTED"/> <tx:method name="delete*" propagation="REQUIRED" isolation="READ_COMMITTED"/> <tx:method name="find*" propagation="SUPPORTS" read-only="true"/> <tx:method name="query*" propagation="SUPPORTS" read-only="true"/> <tx:method name="get*" propagation="SUPPORTS" read-only="true"/> <tx:method name="select*" propagation="SUPPORTS" read-only="true"/> <tx:method name="list*" propagation="SUPPORTS" read-only="true"/> <!-- The name of the method to which the transaction attribute applies,*Represents all methods--> <tx:method name="*"/> </tx:attributes> </tx:advice> <!-- Transaction entry point--> <aop:config> <aop:pointcut id="exp" expression="execution(* com.ssm.service.*Impl.*(..))"/> <!-- Relate tangent expressions to transactions--> <aop:advisor advice-ref="txAdvice" pointcut-ref="exp" /> </aop:config>
4. Spring MVC configuration file
- Annotation scanning
Configuration: the basic package is the software package of presentation layer
Idea: springmvc is only responsible for scanning the class (Controller) of the presentation layer
Parsing: annotation scanning in spinmvc also puts the scanned objects into the IOC container. After the web project is started, the initialization of the Spring container is configured first, and then the front-end Controller (DispatchServlet) of Spring MVC is configured. After the DispatchServlet is configured, a new container will be created in the Spring container. In fact, these are two containers, Spring as the parent container and Spring MVC as the child container (as shown in the figure below). The objects in the Spring MVC child container can access the objects in the Spring parent container, but the objects in the parent container cannot access the objects in the child container. Dao is usually injected into the Service, and then Service is injected into the Controller, which means that as a child container of Spring MVC, Spring objects of the parent container can be accessed. If the Controller is injected into the Service, it will not work. Assuming that Dao, Service and Controller are all placed in the same container, there is no problem with dependency injection between objects, but they must all be in the sub container of Spring MVC (scan all in Spring MVC). If Dao, Service and Controller are placed in the parent container of Spring (scan all in Spring), and there is no Controller object in the Spring MVC container at this time, the mapped Controller object will not be found when loading the processor adapter, so 404 error will appear on the page.
<context:component-scan base-package="com.ssm.controller"/>
- Annotation driven
<mvc:annotation-driven conversion-service="conversionService"/>
- view resolver
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean>
- Formatting and type conversion services
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="com.ssm.util.DateConverter"/> </set> </property> </bean>
- Static resource processing
<mvc:default-servlet-handler/>
- Other configurations
<!-- File upload parser--> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- Set the size of the uploaded file in bytes and the size is 100 MB --> <property name="maxUploadSize" value="104857600"/> <!-- Set the character encoding of the upload--> <property name="defaultEncoding" value="utf-8"/> <!-- Set cache size,Size 10 KB--> <property name="maxInMemorySize" value="10240"/> </bean> <!-- Configuring Interceptors --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <!-- Exclude non blocking paths--> <mvc:exclude-mapping path="/login"/> <bean class="com.ssm.intercepor.LoginInterceptor"/> </mvc:interceptor> </mvc:interceptors> Small, in bytes, size is 100 MB --> <property name="maxUploadSize" value="104857600"/> <!-- Set the character encoding of the upload--> <property name="defaultEncoding" value="utf-8"/> <!-- Set cache size,Size 10 KB--> <property name="maxInMemorySize" value="10240"/> </bean> <!-- Configuring Interceptors --> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <!-- Exclude non blocking paths--> <mvc:exclude-mapping path="/login"/> <bean class="com.ssm.intercepor.LoginInterceptor"/> </mvc:interceptor> </mvc:interceptors>