在實戰中學習Spring,本系列的最終目的是完成一個實現用戶注冊登錄功能的項目。
預想的基本流程如下:
1、用戶網站注冊,填寫用戶名、密碼、email、手機號信息,后臺存入數據庫后返回ok。(學習IOC,mybatis,SpringMVC的基礎知識,表單數據驗證,文件上傳等)
2、服務器異步發送郵件給注冊用戶。(學習消息隊列)
3、用戶登錄。(學習緩存、Spring Security)
4、其他。
邊學習邊總結,不定時更新。項目環境為Intellij + Spring4。
一、準備工作。
1、mysql中建庫建表。
2、Intellij中創建maven webapp工程。
(1) pom.xml中導入需要的依賴包。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
<?xml version= "1.0" encoding= "UTF-8" ?> <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> <groupId>com.everSeeker</groupId> <artifactId>register</artifactId> <packaging>war</packaging> <version> 1.0 </version> <name>register Maven Webapp</name> <url>http: //maven.apache.org</url> <properties> <spring.version> 4.3 . 1 .RELEASE</spring.version> </properties> <dependencies> <!--spring core, context--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <!--test--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version> 4.12 </version> <!--<scope>test</scope>--> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <!--springmvc--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version> 1.1 . 0 .Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version> 5.2 . 4 .Final</version> </dependency> <!--servlet--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version> 3.1 . 0 </version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version> 1.2 </version> </dependency> <!--mysql, mybatis--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version> 6.0 . 3 </version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version> 3.4 . 1 </version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version> 1.3 . 0 </version> </dependency> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version> 0.9 . 1.2 </version> </dependency> </dependencies> <build> <finalName>java_config_web</finalName> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version> 2.2 </version> <configuration> <failOnMissingWebXml> false </failOnMissingWebXml> </configuration> </plugin> </plugins> </build> </project> |
(2) 工程目錄結構如下所示:
二、Mybatis
1、配置mysql數據庫的基本信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
# Database db.mysql.driverClass = com.mysql.jdbc.Driver db.mysql.jdbcUrl = jdbc:mysql: //localhost:3306/register_notice?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true db.mysql.user = root db.mysql.password = 333 db.minPoolSize = 10 db.maxPoolSize = 100 db.initialPoolSize = 20 db.maxIdleTime = 60 db.acquireIncrement = 5 db.maxStatements = 100 db.idleConnectionTestPeriod = 60 db.acquireRetryAttempts = 30 db.breakAfterAcquireFailure = true db.testConnectionOnCheckout = false db.properties |
2、配置mybatis.xml以及spring-mybatis.xml。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
<?xml version= "1.0" encoding= "UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd" > <configuration> <!--配置實體類的別名--> <typeAliases> <!--以下 2 種方法選其一即可。 第 1 種方法:使用typeAlias,為單個類設置別名。--> <!--<typeAlias type= "com.everSeeker.entity.User" alias= "User" />--> <!--第 2 種方法:使用 package ,為包下面的所有類設置別名,默認規則為com.everSeeker.entity.User設置為User,去除前面的包名。--> < package name= "com.everSeeker.entity" /> </typeAliases> </configuration> mybatis.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:tx= "http://www.springframework.org/schema/tx" xmlns:p= "http://www.springframework.org/schema/p" 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/tx http: //www.springframework.org/schema/tx/spring-tx.xsd"> <!-- 在該文件中引入db.properties文件,可以保證之后的配置比如${db.mysql.driverClass}肯定能找到對應的值 --> <!-- 否則,如果直接在RootConfig.java中同事載入db.properties以及spring-mybatis.xml的話,不能保證db.properties先被引入,從而導致程序報錯 --> <context:property-placeholder location= "classpath:db.properties" /> <!--數據源配置 c3p0 常見的數據源實現類包有 2 個,一個是apache的DBCP(org.apache.commons.dbcp.BasicDataSource),另一個為C3P0。 --> <bean id= "dataSource" class = "com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method= "close" > <property name= "driverClass" value= "${db.mysql.driverClass}" /> <property name= "jdbcUrl" value= "${db.mysql.jdbcUrl}" /> <property name= "user" value= "${db.mysql.user}" /> <property name= "password" value= "${db.mysql.password}" /> <!--連接池中保留的最小連接數。 --> <property name= "minPoolSize" value= "${db.minPoolSize}" /> <!--連接池中保留的最大連接數。Default: 15 --> <property name= "maxPoolSize" value= "${db.maxPoolSize}" /> <!--初始化時獲取的連接數,取值應在minPoolSize與maxPoolSize之間。Default: 3 --> <property name= "initialPoolSize" value= "${db.initialPoolSize}" /> <!--最大空閑時間, 60 秒內未使用則連接被丟棄。若為 0 則永不丟棄。Default: 0 --> <property name= "maxIdleTime" value= "${db.maxIdleTime}" /> <!--當連接池中的連接耗盡的時候c3p0一次同時獲取的連接數。Default: 3 --> <property name= "acquireIncrement" value= "${db.acquireIncrement}" /> <!--JDBC的標準參數,用以控制數據源內加載的PreparedStatements數量。但由于預緩存的statements 屬于單個connection而不是整個連接池。所以設置這個參數需要考慮到多方面的因素。 如果maxStatements與maxStatementsPerConnection均為 0 ,則緩存被關閉。Default: 0 --> <property name= "maxStatements" value= "${db.maxStatements}" /> <!--每 60 秒檢查所有連接池中的空閑連接。Default: 0 --> <property name= "idleConnectionTestPeriod" value= "${db.idleConnectionTestPeriod}" /> <!--定義在從數據庫獲取新連接失敗后重復嘗試的次數。Default: 30 --> <property name= "acquireRetryAttempts" value= "${db.acquireRetryAttempts}" /> <!--獲取連接失敗將會引起所有等待連接池來獲取連接的線程拋出異常。但是數據源仍有效 保留,并在下次調用getConnection()的時候繼續嘗試獲取連接。如果設為 true ,那么在嘗試 獲取連接失敗后該數據源將申明已斷開并永久關閉。Default: false --> <property name= "breakAfterAcquireFailure" value= "${db.breakAfterAcquireFailure}" /> <!--因性能消耗大請只在需要的時候使用它。如果設為 true 那么在每個connection提交的 時候都將校驗其有效性。建議使用idleConnectionTestPeriod或automaticTestTable 等方法來提升連接測試的性能。Default: false --> <property name= "testConnectionOnCheckout" value= "${db.testConnectionOnCheckout}" /> </bean> <!-- myBatis配置. classpath和classpath*的區別,參考文檔:http: //blog.csdn.net/zl3450341/article/details/9306983. classpath只會返回第一個匹配的資源,建議確定路徑的單個文檔使用classpath;匹配多個文檔時使用classpath*. --> <bean id= "sqlSessionFactory" class = "org.mybatis.spring.SqlSessionFactoryBean" p:dataSource-ref= "dataSource" p:configLocation= "classpath:mybatis.xml" p:mapperLocations= "classpath*:mapper/*Mapper.xml" /> <bean class = "org.mybatis.spring.mapper.MapperScannerConfigurer" > <!--basePackage指定要掃描的包,在此包之下的映射器都會被搜索到。可指定多個包,包與包之間用逗號或分號分隔 MapperScannerConfigurer將掃描basePackage所指定包下的所有接口類(包括子包),如果他們在SQL映射文件 中定義過,則將他們動態定義為一個Spring Bean. --> <property name= "basePackage" value= "com.everSeeker.dao" /> <property name= "sqlSessionFactoryBeanName" value= "sqlSessionFactory" /> </bean> <!-- 事務管理器配置, 使用jdbc事務 --> <bean id= "transactionManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager" > <property name= "dataSource" ref= "dataSource" /> </bean> <!-- 使用annotation定義事務,對標注了 @Transactional 注解的bean進行處理,以織入事務管理切面. 默認情況下,自動使用名稱為transactionManager的事務管理器。 proxy-target- class 為 true ,表示spring將通過創建子類來代理業務類,需要在類路徑中添加CGLib.jar類庫。--> <tx:annotation-driven transaction-manager= "transactionManager" proxy-target- class = "true" /> </beans> spring-mybatis.xml |
3、創建User類以及UserDao接口。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
public class User { @Size (min = 32 , max = 32 , message = "uuid應該為32位字符串" ) private String id; @Size (min = 1 , max = 32 , message = "賬號長度應該在1-32位之間" ) private String username; @NotEmpty (message = "密碼不能為空" ) private String password; @NotEmpty (message = "email不能為空" ) @Email (message = "email格式不正確" ) private String email; @Size (min = 11 , max = 11 , message = "手機號長度為11位" ) private String cellphone; private long regDate; public User() { this .id = UUID.randomUUID().toString().replaceAll( "-" , "" ); this .regDate = 0 ; } public User(String username, String password, String email, String cellphone) { this (username, password, email, cellphone, new Date().getTime()); } public User(String username, String password, String email, String cellphone, long regDate) { this .id = UUID.randomUUID().toString().replaceAll( "-" , "" ); this .username = username; this .password = password; this .email = email; this .cellphone = cellphone; this .regDate = regDate; } public String getId() { return id; } public void setId(String id) { this .id = id; } public String getUsername() { return username; } public void setUsername(String username) { this .username = username; } public String getPassword() { return password; } public void setPassword(String password) { this .password = password; } public String getEmail() { return email; } public void setEmail(String email) { this .email = email; } public String getCellphone() { return cellphone; } public void setCellphone(String cellphone) { this .cellphone = cellphone; } public long getRegDate() { return regDate; } public void setRegDate( long regDate) { this .regDate = regDate; } @Override public String toString() { return "[User: id=" + id + ", username=" + username + ", password=" + password + ", email=" + email + ", cellphone=" + cellphone + ", regDate=" + regDate + "]" ; } } User.java |
User.java中的@NotNull, @NotEmpty, @Size以及@Email等注釋暫時忽略,以后解釋。
1
2
3
4
5
|
@Repository public interface UserDao { void addUser(User user); User getUserByUsername(String username); } |
4、在src/main/resources/mapper目錄下創建UserMapper.xml映射文件,實現UserDao接口中的方法。注:*Mapper.xml文件必須放在src/main/resources目錄下,之前放在src/main/java/com/everSeeker/dao目錄下,產生了莫名奇妙的錯誤。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?xml version= "1.0" encoding= "UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace= "com.everSeeker.dao.UserDao" > <resultMap id= "ResultMapUser" type= "com.everSeeker.entity.User" > </resultMap> <insert id= "addUser" parameterType= "User" > INSERT INTO user(id, username, password, email, cellphone, regDate) VALUES(#{id}, #{username}, #{password}, #{email}, #{cellphone}, #{regDate}) </insert> <select id= "getUserByUsername" parameterType= "String" resultMap= "ResultMapUser" > SELECT * FROM user WHERE username=#{username} </select> </mapper> UserMapper.xml |
三、IOC
1、創建IOC容器,通過注解方式,RootConfig.java。
1
2
3
4
5
6
7
8
9
10
11
|
@Configuration @ComponentScan (basePackages = { "com.everSeeker" }, excludeFilters = { @ComponentScan .Filter(type = FilterType.CUSTOM, value = RootConfig.WebPackage. class )}) @ImportResource ({ "classpath:spring-mybatis.xml" }) public class RootConfig { public static class WebPackage extends RegexPatternTypeFilter { public WebPackage() { super (Pattern.compile( "com\\.everSeeker\\.web" )); } } } |
@Configuration: 表明這是一個配置類。
@ComponentScan: 啟用組建掃描,basePackages:需要掃描的基礎package。excludeFilters: 符合filter條件的不掃描。
@ImportResource: 引入xml文件。
@PropertySource: 引入properties文件。
2、由于創建的是webapp項目,并且采用了SpringMVC,那么DispatcherServlet是核心。以前的Spring版本中,一般會配置在web.xml中。而在Spring4中,可以在Java代碼中來實現。WebAppInitializer.java。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { //繼承了AbstractAnnotationConfigDispatcherServletInitializer的類會自動配置DispatcherServlet和Spring應用上下文 @Override protected String[] getServletMappings() { //將DispatcherServlet映射到"/" return new String[] { "/" }; } /** * RootConfig類用來配置ContextLoaderListener創建的應用上下文中的bean, * 比如@Repository, @Service等組件 */ @Override protected Class<?>[] getRootConfigClasses() { return new Class<?>[] { RootConfig. class }; } /** * DispatcherServlet加載應用上下文時,使用定義在WebConfig配置類中的bean, * 用來加載包含Web組件的bean,比如控制器,視圖解析器以及處理器映射, @Controller, @RequestMapping等 */ @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[] { WebConfig. class }; } @Override protected void customizeRegistration(ServletRegistration.Dynamic registration) { //限制上傳文件的大小不超過2MB,整個請求不超過4M,所有上傳的文件都要寫到磁盤中 registration.setMultipartConfig( new MultipartConfigElement( "/tmp/uploads" , 2097152 , 4194304 , 0 )); } } |
3、創建WebConfig.java。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
@Configuration @EnableWebMvc @ComponentScan ( "com.everSeeker.web" ) public class WebConfig extends WebMvcConfigurerAdapter { //配置jsp視圖解析器 @Bean public ViewResolver viewResolver() { InternalResourceViewResolver resourceViewResolver = new InternalResourceViewResolver(); resourceViewResolver.setPrefix( "/WEB-INF/views/" ); resourceViewResolver.setSuffix( ".jsp" ); resourceViewResolver.setExposeContextBeansAsAttributes( true ); return resourceViewResolver; } //配置multipart解析器, 上傳文件用 @Bean public MultipartResolver multipartResolver() throws IOException { return new StandardServletMultipartResolver(); } //配置靜態資源的處理 @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } } |
@Bean: 聲明這個方法會創建所需類型的實例,并注冊為Spring應用上下文中的bean。
以上所述是小編給大家介紹的Spring學習筆記1之IOC詳解盡量使用注解以及java代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!
原文鏈接:http://www.cnblogs.com/everSeeker/p/5667503.html