Spring 配置文件
Bean 标签配置
<bean id="userDao" class="com.vsneko.dao.impl.UserDaoImpl" scope="singleton"></bean>
|
- singleton:默认值,单例的。
- 对象创建:当应用加载,创建容器时,对象被创建。
- 对象运行:只要容器在,对象一直活着。
- 对象销毁:当应用卸载,销毁容器时,对象被销毁。
- prototype:多例的。
- 对象创建:使用对象时,创建新的对象实例。
- 对象运行:只要对象在使用中,就一直活着。
- 对象销毁:当对象长时间不用时,被 Java 的垃圾回收器回收。
- request:WEB 项目中,Spring 创建一个 Bean 对象,将对象存入到 request 域中。
- session:WEB 项目中,Spring 创建一个 Bean 对象,将对象存入到 session 域中。
- global session:WEB 项目中,应用在 Portlet 环境,如果没有 Portlet 环境,那么 globalSession 相当于 session。
Bean 标签范围配置
<bean id="userDao" class="com.vsneko.dao.impl.UserDaoImpl" init-method="init" destroy-method="destroy"></bean>
|
- init-method:指定类中的初始化方法名称。
- destroy-method:指定类中销毁方法名称。
Bean 实例化的三种方式
无参构造方法实例化
<bean id="userDao" class="com.vsneko.dao.impl.UserDaoImpl"></bean>
|
工厂静态方法实例化
<bean id="userDao" class="com.vsneko.factory.StaticFactory" factory-method="getUserDao"></bean>
|
工厂实例方法实例化
<bean id="factory" class="com.vsneko.factory.DynamicFactory"></bean> <bean id="userDao" factory-bean="factory" factory-method="getUserDao"></bean>
|
Bean 依赖注入方式
Set 方法注入
public UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; }
|
<bean id="userDao" class="com.vsneko.dao.impl.UserDaoImpl"></bean> <bean id="userService" class="com.vsneko.service.impl.UserServiceImpl"> <property name="userDao" ref="userDao"></property> </bean>
|
<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans">
<bean id="userDao" class="com.vsneko.dao.impl.UserDaoImpl"></bean> <bean id="userService" class="com.vsneko.service.impl.UserServiceImpl" p:userDao-ref="userDao"/>
</beans>
|
使用构造方法注入
public UserDao userDao; public UserServiceImpl() {} public UserServiceImpl(UserDao userDao) { this.userDao = userDao; }
|
<bean id="userDao" class="com.vsneko.dao.impl.UserDaoImpl"></bean> <bean id="userService" class="com.vsneko.service.impl.UserServiceImpl"> <constructor-arg name="userDao" ref="userDao"></constructor-arg> </bean>
|
Bean 依赖注入的数据类型
普通数据类型
private String name; private String addr;
|
<bean id="u1" class="com.vsneko.domain.User"> <property name="name" value="Zhangsan"></property> <property name="addr" value="Beijing"></property> </bean>
|
引用数据类型
private List<String> strList; private Map<String, User> userMap; private Properties properties;
|
<bean id="userDao" class="com.vsneko.dao.impl.UserDaoImpl"> <property name="strList"> <list> <value>aaa</value> <value>bbb</value> <value>ccc</value> </list> </property>
<property name="userMap"> <map> <entry key="user1" value-ref="u1"></entry> <entry key="user2" value-ref="u2"></entry> </map> </property>
<property name="properties"> <props> <prop key="p1">ppp1</prop> <prop key="p2">ppp2</prop> </props> </property> </bean>
|
引入其他配置文件(分模块开发)
<import resource="applicationContext-user.xml" />
|
ApplicationContext 的实现类
ClassPathXmlApplicationContext
它是从类的根路径下加载配置文件,推荐使用。
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) app.getBean("userService");
|
FileSystemXmlApplicationContext
它是从磁盘路径下加载配置文件,配置文件可以在磁盘的任意位置。
ApplicationContext app = new FileSystemXmlApplicationContext("path");
|
AnnotationConfigApplicationContext
当使用注解配置容器对象时,需要使用此类来创建 spring 容器,它用来读取注解。
Spring 配置数据源
数据源(连接池)的作用
- 数据源(连接池)是提高程序性能的。
- 事先实例化数据源,初始化部分连接资源。
- 使用连接资源时从数据源中获取。
- 使用完毕后将连接资源归还给数据源。
数据源的手动创建
- 在
pom.xml
文件中导入 c3p0
和 druid
的坐标。
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.20</version> </dependency> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.10</version> </dependency>
|
- 在方法中配置数据源
ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setDriverClass("com.mysql.jdbc.Driver"); dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test"); dataSource.setUser("root"); dataSource.setPassword("root");
Connection connection = dataSource.getConnection(); System.out.println(connection); connection.close();
|
DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/test"); dataSource.setUsername("root"); dataSource.setPassword("root");
DruidPooledConnection connection = dataSource.getConnection(); System.out.println(connection); connection.close();
|
- 提取配置文本到配置文件
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/test jdbc.username=root jdbc.password=root
|
ResourceBundle rb = ResourceBundle.getBundle("jdbc"); rb.getString("jdbc.driver"); rb.getString("jdbc.url"); rb.getString("jdbc.username"); rb.getString("jdbc.password");
|
Spring 配置数据源
可以将 DataSource 的创建权交由 Spring 容器去完成。
- 在 pom.xml 文件中导入
spring-context
的坐标。
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.7.RELEASE</version> </dependency>
|
- 在
applicationContext.xml
中配置注入
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property> <property name="user" value="root"></property> <property name="password" value="root"></property> </bean>
|
- 使用
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); DataSource dataSource = (DataSource) app.getBean(DataSource.class);
Connection connection = dataSource.getConnection(); System.out.println(connection); connection.close();
|
XML 加载配置文件
需要引入 context 命名空间
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" 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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driver}"></property> <property name="jdbcUrl" value="${jdbc.url}"></property> <property name="user" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean>
</beans>
|
Spring 原始注解
Spring 原始注解主要是替代 <Bean>
的配置
注解列表
注解 |
说明 |
@Component |
使用在类上,用于实例化 Bean |
@Controller |
使用在 Web 层类上,用于实例化 Bean |
@Service |
使用在 Service 层类上,用于实例化 Bean |
@Repository |
使用在 Dao 层类上,用于实例化 Bean |
@Autowired |
使用在字段上,用于根据类型依赖注入 |
@Qualifier |
结合 @Autowired 一起使用,用于根据名称进行依赖注入 |
@Resource |
结合 @Autowired + @Qualifier 一起使用,按照名称进行注入 |
@Value |
注入普通属性 |
@Scope |
标注 Bean 的作用范围 |
@PostConstruct |
使用在方法上,标注该方法是 Bean 的初始化方法 |
@PreDestroy |
使用在方法上,标注该方法是 Bean 的销毁方法 |
注解的使用
- 在需要配置的Bean类上面加上注解
@Component("id")
( @Repository, @Service, @Controller
)。
@Repository("userDao") public class UserDaoImpl implements UserDao { public void save() { System.out.printf("save running"); } }
|
- 如果要注入属性,可以用
@Autowired
和 @Qualifier
来注入。
@Service("userService") public class UserServiceImpl implements UserService {
@Autowired @Qualifier("userDao") private UserDao userDao; public void save() { userDao.save(); } }
|
- 要在
applicationContext.xml
配置文件中,配置组件扫描(需要引入Context包)。
<?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">
<context:component-scan base-package="com.vsneko"></context:component-scan> </beans>
|
注解使用一些细节
@Repository, @Service, @Controller
和 @Component
是一样的效果,只是具有语义化,增加可读性。
- 对于属性,如果只标记
@Autowired
,也是可以注入的,这个时候 Spring 会根据属性的类型来匹配 Spring 容器中的 Bean 进行注入。
- 如果标记
@Autowired
的属性类型在容器中有多个 Bean,则需要用到 @Qualifier
来标识注入的 Bean 的 id,@Qualifier
必须配合 @Autowired
来使用。
- 如果同时使用
@Autowired
和 @Qualifier
,则可以使用 @Resource
来代替。
@Service("userService") public class UserServiceImpl implements UserService {
@Resource(name="userDao") private UserDao userDao; public void save() { userDao.save(); } }
|
注入普通属性值
使用 @Value
注解可以注入普通属性值,可以使用 ${key}
来注入配置项的值。
<context:property-placeholder location="classpath:jdbc.properties"/>
|
@Service("userService") public class UserServiceImpl implements UserService {
@Value("abc") private String text;
@Value("${jdbc.driver}") private String driver; }
|
注解标记 Bean 的作用范围
使用 @Scope
注解可以标记 Bean 的作用范围 (单例: singleton, 多例: prototype)。
@Service("userService") @Scope("singleton") public class UserServiceImpl implements UserService {
}
|
注解标记 Bean 的创建和销毁方法
使用 @PostConstruct
和 @PreDestroy
注解可以标记 Bean 的创建和销毁方法。
@Service("userService") public class UserServiceImpl implements UserService {
@PostConstruct public void init(){ System.out.printf("init"); } @PreDestroy public void destroy(){ System.out.printf("destroy"); } }
|
Spring 新注解
以下配置无法使用原始注解来代替,这时需要使用新注解。有了新注解,可以完全替代配置文件。
- 非自定义的 Bean 配置
- 加载 properties 文件的配置
- 组件扫描的配置
- 引入其他文件的配置
新注解列表
注解 |
说明 |
@Configuration |
用于指定当前类是一个 Spring 配置类,创建容器时会从该类上加载注解 |
@ComponentScan |
用于指定 Spring 初始化容器时要扫描的包。 |
@Bean |
用在方法上,标注将该方法的返回值存储在 Spring 容器中。 |
@PropertySource |
用于加载 properties 文件中的配置 |
@Import |
用于导入其他配置类 |
新注解的使用
@Configuration
@ComponentScan("com.vsneko")
@Import({DataSourceConfiguration.class}) public class SpringConfiguration {
}
|
@PropertySource("classpath:jdbc.properties") public class DataSourceConfiguration {
@Value("${jdbc.driver}") private String driver;
@Value("${jdbc.url}") private String url;
@Value("${jdbc.username}") private String username;
@Value("${jdbc.password}") private String password;
@Bean("dataSource") public DataSource getDataSource() throws PropertyVetoException { ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setDriverClass(driver); dataSource.setJdbcUrl(url); dataSource.setUser(username); dataSource.setPassword(password); return dataSource; } }
|
测试
public class TestMain { public static void main(String[] args) { ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfiguration.class); UserService userService = (UserService) app.getBean("userService"); userService.save(); } }
|
Spring 集成 Junit
步骤
- 导入 Spring 集成 Junit 的坐标
<dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.2.7.RELEASE</version> </dependency>
|
- 使用
@Runwith
注解来替换原来的运行期
@RunWith(SpringJUnit4ClassRunner.class)
|
- 使用
@ContextConfiguration
指定配置文件或配置类
@ContextConfiguration(classes = {SpringConfiguration.class})
|
- 使用
@Autowired
注入需要测试的对象
@Autowired private UserService userService;
|
- 创建测试方法进行测试
@Test public void test1() { userService.save(); }
|
示例
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class}) public class SpringJunitTest {
@Autowired private UserService userService;
@Test public void test1() { userService.save(); } }
|
Spring ContextLoaderListener
导入 spring-web 坐标
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.7.RELEASE</version> </dependency>
|
配置上下文对象
使用 WebApplicationContextUtils 来获得应用上下文对象 ApplicationContext
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
|
使用
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext servletContext = this.getServletContext();
WebApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext); UserService bean = app.getBean(UserService.class); bean.save(); }
|