提交 05a6f4f6 编写于 作者: 凉拌糖醋鱼's avatar 凉拌糖醋鱼 💬

Update Spring快速上手.md

上级 dabb013c
......@@ -6,8 +6,6 @@
Spring是分层的JavaSE/EE应用full-stack(全栈的)轻量级开源框架,它有两个核心思想:**IoC**(Inverse of Control,控制反转)和 **AOP**(Aspect Oriented Programming,面向切面编程),提供了展现层 SpringMVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,现在逐渐成为最受欢迎的JavaEE企业开源开发框架。
![核心架构](../../../图片/博客/Spring_Structure.jpg)
## 为什么使用Spring框架——Spring框架的优点
1. **便于程序间解耦,使得开发更简洁**
......@@ -486,6 +484,56 @@ http://www.springframework.org/schema/beans/spring-beans.xsd">
|1|Zero|1559503|
|2|Sharon|155345|
#### Maven坐标pom.xml
```xml
<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>top.aerlee</groupId>
<artifactId>shogirlsAnnowithoutxml</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>shogirlsAnnowithoutxml</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
</dependencies>
</project>
```
#### 实体类,业务层及Dao层类
```java
......@@ -609,7 +657,7 @@ public class GirlDaoImpl implements GirlDao{
#### 配置Spring Ioc(编写xml配置文件)
我们打算使用ClassPathXmlApplicationContext,所以我们xml文件放在main.java包下,命名为beans.xml
我们打算使用ClassPathXmlApplicationContext,所以我们xml文件放在main.java包下,命名为beans.xml
```xml
<?xml version="1.0" encoding="UTF-8"?>
......@@ -619,12 +667,12 @@ public class GirlDaoImpl implements GirlDao{
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 配置业务层对象 -->
<bean id="service" class="top.aerlee.service.impl.GirlServiceImpl">
<!-- 注入业务层中引用dao对象 -->
<!-- 注入业务层中引用dao对象 -->
<property name="dao" ref="dao"></property>
</bean>
<!-- 配置dao层对象 -->
<bean id="dao" class="top.aerlee.dao.impl.GirlDaoImpl">
<!-- 注入dao层引用QueryRunner对象 -->
<!-- 注入dao层引用QueryRunner对象 -->
<property name="runner" ref="runner"></property>
</bean>
<!-- 配置QueryRunner对象,并设置为多例模式 -->
......@@ -860,9 +908,73 @@ public static void main(String[] args) {
}
```
### 摆脱xml配置文件实现纯注解配置
### 摆脱xml配置文件实现纯注解配置Spring IoC
通过定义一个类,在该类上面添加相应的注解来配置之前在xml中的配置。还是基于前面我们的数据库查询案例,不过这里将使用配置类来替代xml配置文件。接口没有变化,只是在接口的实现类中,我们改用注解实现对象创建及依赖注入。
```java
package top.aerlee.dao.impl;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import top.aerlee.dao.GirlDao;
import top.aerlee.domain.Girl;
/**
* Dao层实现类
* @author vincent
*
*/
@Repository("daoAnno")
public class GirlDaoAnnoImpl implements GirlDao{
@Autowired
private QueryRunner runner;
public void setRunner(QueryRunner runner) {
this.runner = runner;
}
public List<Girl> showAll() {
List<Girl> list = null;
try {
list = runner.query("select * from girls", new BeanListHandler<Girl>(Girl.class));
} catch (Exception e) {
e.printStackTrace();
}
return list;
}
}
```
通过定义一个类,在该类上面添加相应的注解来配置之前在xml中的配置。
```java
package top.aerlee.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.aerlee.dao.GirlDao;
import top.aerlee.domain.Girl;
import top.aerlee.service.GirlService;
/**
* 业务层实现类
* @author vincent
*
*/
@Service("serviceAnno")
public class GirlServiceAnnoImpl implements GirlService{
@Autowired
private GirlDao dao;
public void setDao(GirlDao dao) {
this.dao = dao;
}
public List<Girl> showAll() {
return dao.showAll();
}
}
```
#### @Configuration
......@@ -907,3 +1019,303 @@ public class Springconfig {
}
```
#### @Bean
该注解只能写在方法上,表明使用此方法创建一个对象,并且放入 Spring 容器。
属性:name,给当前@Bean 注解方法创建的对象指定一个名称,即 bean 的 id。
```java
package top.aerlee.configurations;
import javax.sql.DataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import com.mchange.v2.c3p0.ComboPooledDataSource;
/**
* 配置类
* @author vincent
*/
@Configuration
@ComponentScan("top.aerlee")
public class SpringConfig {
@Bean(name = "runner")
public QueryRunner createRunner(DataSource datasource) {
return new QueryRunner(datasource);
}
@Bean(name = "datasource")
public DataSource createDataSource() {
ComboPooledDataSource cds = new ComboPooledDataSource();
try {
cds.setDriverClass("com.mysql.jdbc.Driver");
cds.setJdbcUrl("jdbc:mysql://localhost:3306/girlsinfo");
cds.setUser("数据库用户名");
cds.setPassword("密码");
return cds;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
return cds;
}
}
```
在这里使用了@Bean注解,在配置类中将DataSource对象创建并且加入到了Spring容器中,但是这样还是有一个问题,那就是关于数据库连接相关的配置都被写死在了配置类中,如果遇到了更换数据库连接等情况的话,还要更改源代码,是比较麻烦的。使用@@PropertySource注解可以解决这个问题。
#### @PropertySource
用于加载 .properties文件中的配置 。 例如:我们配置数据源时 , 可以把连接数据库的信properties配置文件中,就可以使用此注解指定properties配置文件的位置。
属性:value[]:用于指定properties文件位置。如果是在类路径下,需要写上"classpath:",在前面我们讲过,如果使用@Value注解来注入数据的时候,是支持"SPEL表达式"的。
我们可以将数据库连接信息写成一个JdbcLink.properties配置文件放在类路径下,在配置文件中使用@PropertySource注解来配置。
```reStructuredText
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/girlsinfo
username=vincent
password=vincent12345
```
```java
package top.aerlee.configurations;
import javax.sql.DataSource;
import org.apache.commons.dbutils.QueryRunner;
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.PropertySource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
/**
* 配置类
* 在这里我们使用了@PropertySource注解将之前配置在JdbcLink.properties配置文件中的连接数据引入
* 从而解决了前面提到的配置信息写死的问题。
* @author vincent
*
*/
@Configuration
@ComponentScan("top.aerlee")
@PropertySource("classpath:JdbcLink.properties")
public class SpringConfig2 {
// 定义数据库连接相关信息对应的变量
@Value("${driver}")
private String driver;
@Value("${url}")
private String url;
@Value("${username}")
private String username;
@Value("${password}")
private String password;
@Bean(name = "runner")
public QueryRunner createRunner(DataSource datasource) {
return new QueryRunner(datasource);
}
@Bean(name = "datasource")
public DataSource createDataSource() {
ComboPooledDataSource cds = new ComboPooledDataSource();
try {
cds.setDriverClass(driver);
cds.setJdbcUrl(url);
cds.setUser(username);
cds.setPassword(password);
return cds;
} catch (Exception e) {
e.printStackTrace();
}
return cds;
}
}
```
#### @Import
用于导入其他配置类
属性:value[]:用于指定其他配置类的字节码。
在实际的开发中,我们需要配置的内容显然不止JDBC,为了便于维护,我们可以将配置写在多个配置类中,成为子配置类,而SpringConfig类就是主配置类,当我们将子配置类写好之后,在主配置类中使用@Import注解可以将子配置类引入。
```java
package top.aerlee.configurations;
import javax.sql.DataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
/**
* 子配置类,在主配置类中通过@Import注解来导入
* @author vincent
*/
@Configuration
@PropertySource("classpath:JdbcLink.properties")
public class JdbcConfig {
@Value("${driver}")
private String driver;
@Value("${url}")
private String url;
@Value("${username}")
private String username;
@Value("${password}")
private String password;
@Bean(name = "runner")
public QueryRunner createRunner(DataSource datasource) {
return new QueryRunner(datasource);
}
@Bean(name = "datasource")
public DataSource createDataSource() {
ComboPooledDataSource cds = new ComboPooledDataSource();
try {
cds.setDriverClass(driver);
cds.setJdbcUrl(url);
cds.setUser(username);
cds.setPassword(password);
return cds;
} catch (Exception e) {
e.printStackTrace();
}
return cds;
}
}
```
```java
package top.aerlee.configurations;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
/**
* 主配置类
* 在这里,我们使用了@Import注解将JdbcConfig配置类导入了主配置类中
* @author vincent
*/
@Configuration
@ComponentScan("top.aerlee")
@Import(JdbcConfig.class)
public class SpringConfig {
}
```
#### 创建纯注解环境的容器
在使用xml或者使用半注解配置Spring IoC时,我们使用了`ClassPathXmlApplicationContext`类来创建Spring IoC容器,而现在我们使用纯注解的方式来配置,将使用`AnnotationConfigApplicationContext`类来创建容器,它的参数不再是配置文件,而是配置类的class。
```java
package top.aerlee.test;
import java.util.List;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import top.aerlee.configurations.SpringConfig;
import top.aerlee.domain.Girl;
import top.aerlee.service.GirlService;
import top.aerlee.service.impl.GirlServiceAnnoImpl;
public class TestIoCAnno {
@Test
public void TestShowAll() {
AnnotationConfigApplicationContext aContext = new AnnotationConfigApplicationContext(SpringConfig.class);
GirlService service = (GirlService)aContext.getBean("serviceAnno",GirlServiceAnnoImpl.class);
List<Girl> list = service.showAll();
for(Girl girl : list) {
System.out.println(girl);
}
aContext.close();
}
}
```
## Spring 整合Junit测试功能
在上面的测试案例中,因为在程序运行之前我们需要创建容器,我们将创建容器的代码写在了Test方法中,这意味着,每个@Test方法中我们都要写这部分代码。在以前,我们使用@Before注解来将这部分代码提取出去;但是在实际开发中,测试工程师和软件开发工程师是两个岗位,我们想要的是直接让它自动创建容器,这就需要整合Spring和Junit。Junit无法实现自动创建Spring容器的功能,但是Junit提供了一个注解@Runwith,它支持将Junit的运行器改为Spring提供的运行器,它可以自动创建容器。
### 配置整合环境
导入坐标,我们需要一个spring-test的jar包,和Junit4.12以上的包,同时spring-aop的jar包也是必须的。
```xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
```
### 使用@RunWith 注解替换原有运行器
````java
@RunWith(SpringJUnit4ClassRunner.class)
public class TestIoCAnno {
}
````
### 使用@ContextConfiguration注解指定 spring 配置文件的位置
如果使用的是xml文件配置的,那么就使用locations属性指定配置文件打位置,如果使用的是注解配置的,那就使用classes属性指定配置类的classes文件。
```java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=SpringConfig.class)
public class TestIoCAnno {
}
```
```java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:bean.xml")
public class TestIoCAnno {
}
```
### 使用@Autowired 给测试类中的变量注入数据
```java
package top.aerlee.test;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import top.aerlee.configurations.SpringConfig;
import top.aerlee.domain.Girl;
import top.aerlee.service.GirlService;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=SpringConfig.class)
public class TestIoCAnno {
@Autowired
GirlService service;
@Test
public void TestShowAll() {
List<Girl> list = service.showAll();
for(Girl girl : list) {
System.out.println(girl);
}
}
}
```
在这里,不再需要容器对象了,因为使用Spring整合Junit的方式的话,容器会自动创建,容器创建后,GirlService对象也会被创建,在这里直接使用@Autowired注解注入即可。
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册