目录
-
Spring相关API
- ApplicationContext的继承体系
- ApplicationContext的实现类
- ClassPathXmlApplicationContext类
- FileSystemXmlApplicationContext类
- AnnotationConfigApplicationContext类
- getBean()方法的使用
- 参数为Bean的id
- 参数为Bean.class
- Spring的重点API
-
Spring配置数据源
- 数据源(连接池)的作用
- 手动配置数据源C3P0、Druid等
- 设置jar包的坐标
- 从数据源获取对象
- 调用数据源对象的set方法参数(也可以新建properties文件,绑定获取参数再进行设置)
- 获取连接对象
- 归还对象
- Spring配置数据源步骤
- 设置Spring的坐标和jar包的坐标
- 配置applicationContext.xml无参构造获取数据源对象、set方法属性参数注入
- 为了解耦合,可以抽取jdbc.properties配置文件
- applicationContext.xml引入context命名空间、约束路径
- applicationContext.xm使用SpEL加载外部properties文件
-
Spring注解开发
- 原始注解
- 入门使用
- 业务层、服务层、持久层注解使用
- 一般属性值的注入
- Spring新注解
- 新注解的入门使用
-
Spring整合Junit
- Spring集成Junit步骤
开始
一、Spring相关API
1.1ApplicationContext的继承体系
1.2ApplicationContext的实现类
对应上述的绿色部分
- ClassPathXmlApplicationContext类
- FileSystemXmlApplicationContext类
- AnnotationConfigApplicationContext类
1.3getBean()方法的使用
- 参数为Bean的id
- 参数为Bean.class
注意:
当容器中只存在某种类型Bean的一个对象时候,上述两种方法都可
但是若容器中存在同种Bean的多种对象的时候,只能通过id来获取,使用Bean.class会报错
1.4Spring的重点API
二、Spring配置数据源
数据源就是各种连接池的又一个名称
2.1数据源(连接池)的作用
作用就是能简化 繁琐的资源申请资源释放,提高程序的性能
2.2手动配置数据源C3P0、Druid等(自己new数据源对象)
-
设置jar包的坐标
-
从数据源获取对象
-
调用数据源对象的set方法参数(也可以新建properties文件,绑定获取参数再进行设置)
-
获取连接对象
-
归还对象
package henu.soft.xiaosi.test;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import java.beans.PropertyVetoException;
import java.sql.Connection;
public class DataSourceTest {
@Test
public void test1() throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql:///javaweb");
dataSource.setUser("root");
dataSource.setPassword("720720");
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
}
- 关于配置文件的解耦合
上述办法虽然可行,但是数据源参数都是写死的,耦合度太高,我们需要将数据源的配置信息抽取到properties文件
然后需要绑定加载配置文件,然后设置
需要注意的是,ResourceBundle.getBundle()
加载配置文件的方法参数 不需要后缀名
package henu.soft.xiaosi.test;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.util.ResourceBundle;
public class DataSourceTest {
@Test
public void test1() throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql:///javaweb");
dataSource.setUser("root");
dataSource.setPassword("720720");
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
@Test
public void test2() throws Exception {
ResourceBundle rb = ResourceBundle.getBundle("jdbc");
String driver = rb.getString("jdbc.driver");
String url = rb.getString("jdbc.url");
String username = rb.getString("jdbc.username");
String password = rb.getString("jdbc.password");
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);
Connection connection = dataSource.getConnection();
System.out.println(connection);//com.mchange.v2.c3p0.impl.NewProxyConnection@2b91004a
connection.close();
}
}
2.3Spring配置数据源步骤(从容器中获取数据源对象)
-
设置Spring的坐标和jar包的坐标
-
配置applicationContext.xml无参构造获取数据源对象、set方法属性参数注入
Test public void test3() throws Exception { ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); DataSource dataSource = app.getBean(DataSource.class); Connection connection = dataSource.getConnection(); System.out.println(connection);//com.mchange.v2.c3p0.impl.NewProxyConnection@74f5ce22 connection.close(); }
-
为了解耦合,可以抽取jdbc.properties配置文件
同样的是,配置文件在applicationContext.xml中写死了,我们需要解耦合抽取配置文件到外部,然后在xml中动态加载
加载使用SPEL的方式,类似EL表达式
-
applicationContext.xml引入context命名空间、约束路径
-
applicationContext.xm使用SpEL加载外部properties文件
三、Spring注解开发
根据逻辑时间,注解分为:
- 原始注解(出现的较早)
- 新注解
轻代码,重配置,注解配置相比xml配置更快捷更高效
3.1原始注解
Spring原始注解主要是替代<Bean>
的配置
- @Component
- @Controller:Component衍生注解,用在web层
- @Service:Component衍生注解,用在service层
- @Repository:Component衍生注解,用在dao层
- @Autowired:依赖输入
- @Qualifier:和Autowired一起使用根据名称依赖注入
- @Resource:相当于Autowried + Qualifier
- @Value:注入普通属性
- @Scope:标注Bean的范围
- @PostConstruct
- @PreDestory
2.2入门使用
使用步骤:
- 在需要的Bean类上面加注解
//<bean id="userDao" class="henu.soft.xiaosi.dao.impl.UserDaoImpl"></bean>
---->@Component("userDao")
//<bean id="userDao" class="henu.soft.xiaosi.dao.impl.UserDaoImpl"></bean>
—>@Component("userDao")
- 有依赖注入的需要在类内加注解
//注入操作在容器中,替换 <property name="userDao" ref="userDao"></property>
—>
@Autowired
@Qualifier("userDao")
- 在xml配置组件扫描
<context:component-scan base-package="henu.soft.xiaosi"></context:component-scan>
部分代码
- UserDaoImpl
package henu.soft.xiaosi.dao.impl;
import henu.soft.xiaosi.dao.UserDao;
import org.springframework.stereotype.Component;
//<bean id="userDao" class="henu.soft.xiaosi.dao.impl.UserDaoImpl"></bean>
@Component("userDao")
public class UserDaoImpl implements UserDao {
public void show() {
System.out.println("show....");
}
}
- UserServiceImpl
package henu.soft.xiaosi.service.impl;
import henu.soft.xiaosi.dao.UserDao;
import henu.soft.xiaosi.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
//<bean id="userService" class="henu.soft.xiaosi.service.impl.UserServiceImpl">
@Component("userService")
public class UserServiceImpl implements UserService {
private UserDao userDao;
//注入操作在容器中,替换 <property name="userDao" ref="userDao"></property>
@Autowired
@Qualifier("userDao")
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void show() {
userDao.show();
}
}
- applicationContext.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"
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">
<!-- 现在使用注解配置替换xml配置-->
<!-- <bean id="userDao" class="henu.soft.xiaosi.dao.impl.UserDaoImpl"></bean>-->
<!-- <bean id="userService" class="henu.soft.xiaosi.service.impl.UserServiceImpl">-->
<!-- <property name="userDao" ref="userDao"></property>-->
<!-- </bean>-->
<!-- 配置组件扫描-->
<context:component-scan base-package="henu.soft.xiaosi"></context:component-scan>
</beans>
注意:
-
xml配置的方式,Bean的
set方法
必须写(UserServiceImpl中注入UserDaoImpl则必须要写setUserDao()
的方法) -
对于注解配置,则不需要写
setUserDaoImpl()
方法 -
@Autowired
注解(类型注入)是自动从容器中找一个如UserDao类型的Bean,只适合容器中的单个Bean对象,下面@Qualifier("userDao")
(名称注入)是根据bean的id来从容器中匹配获取,需要结合二者一起用 -
@Resource
(类型+名称注解)相当于上述二者的结合,是J2EE的注解,JDK9之后需要导入才能使用<dependency> <groupId>javax.annotation</groupId> <artifactId>javax.annotation-api</artifactId> <version>1.3.2</version> </dependency>
2.3业务层、服务层、持久层注解使用
代替Component注解,增加语义标识性
- @Controller:Component衍生注解,用在web层
- @Service:Component衍生注解,用在service层
- @Repository:Component衍生注解,用在dao层
2.4一般属性值的注入
2.5Spring新注解
原始注解可以配置自定义的Bean,但是遇到像数据源这样第三方写好的Bean,原始注解就不能配置了
像C3P0的数据源参数的配置,需要使用新注解
- 非自定义的Bean的配置
- 加载properties配置文件
- 组件扫描配置
- 引入其他文件(配置xml的拆分)
- @Configuration
- @componetScan
- @Bean
- @PropertySource
- @Import
2.6新注解入门使用
需要一种新替代思想,就是 使用一个 核心配置类 代替xml
- 使用类代替xml文件
- 注解代替标签
但是此时数据源配置信息又耦合了,我们需要抽取配置文件,在类内实现配合普通数据类型注入 ,
然后根据键值加载
对于配置是多方面的,我们有时需要划分块,分多个配置类,
如我们将数据源的配置单独写入到一个DataSourceConfiguration类中,然后在主 配置类 中 @Import引入该数据源配置类
最后修改web层
- pom.xml
<?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>org.example</groupId>
<artifactId>Spring_ioc_anno</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.17</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- 指定JDK的版本-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<java.version>11</java.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
</project>
- config.SpringConfiguration
package henu.soft.xiaosi.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException;
@Configuration
@ComponentScan("henu.soft.xiaosi")
public class SpringConfiguration {
@Bean("dataSource")
public DataSource getDataSource() throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql:///javaweb");
dataSource.setUser("root");
dataSource.setPassword("720720");
return dataSource;
}
}
- config.DataSourceConfiguration
package henu.soft.xiaosi.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.SQLException;
@Configuration
@ComponentScan("henu.soft.xiaosi")
@Import({DataSourceConfiguration.class})
public class SpringConfiguration {
}
- UserController
package henu.soft.xiaosi.web;
import henu.soft.xiaosi.config.SpringConfiguration;
import henu.soft.xiaosi.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import javax.sql.DataSource;
public class UserController {
public static void main(String[] args) {
//ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class);
//UserService userService = app.getBean(UserService.class);
DataSource dataSource =(DataSource) app.getBean(DataSource.class);
System.out.println(dataSource);
}
}
- 解耦合的时候报了错,说是找不到jdbc.properties配置文件
但是文件确实存在,搞了很大一会,检查了每个地方,最后才发现问题出在了 偷懒(我直接从另一个项目cv过来的jdbc.properties,问题就出在这里),后来我新建了一个jdbc1.properties,然后就能行了
这里需要提醒,对于项目中的文件cv,有的时候不能成功,导致文件不存在,需要小心
最后成功
四、Spring整合Junit
Spring的测试不是那么方便,因此需要整合JUnit
每次测试都需要获取Spring容器,很不方便
- 用SpringJunit负责创建Spring容器对象app,但是需要将配置文件的名称告诉他
- 将需要进行测试的Bean直接在测试类中进行
4.1Spring集成JUnit步骤
- 导入Spring集成的JUnit的坐标:Spring-test包、Junit包
- 使用@Runwith注解替代:指定是谁完成测试,之前测试使用Junit,现在是先找Spring,Spring再找Junit
- 使用@ContextConfiguration指定配置文件或者配置类
- 使用@Autowire注入需要测试的对象
- 创建测试方法进行测试
原先右键直接找Junit
现在是找SpringJunit,由它完成Spring容器的创建,配置文件加载等,然后再找Junit
- SpringJunitTest
遇到的问题:
-
报了一个错
java.lang.IllegalStateException: Could not load TestContextBootstrapper [null]. Specify @BootstrapWith's 'value' attribu...
-
原因:导入的Junit包版本不兼容
-
解决:重新导入
最后成功 -
SpringJunittest
package henu.soft.xiaosi.test;
import henu.soft.xiaosi.config.SpringConfiguration;
import henu.soft.xiaosi.service.UserService;
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 javax.sql.DataSource;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
@Autowired
private UserService userService;
@Autowired
private DataSource dataSource;
@Test
public void test1(){
userService.show();
System.out.println(dataSource);
}
}