一、配置文件
1. Bean标签
scope: 指对象的作用范围
取值范围 | 说明 |
---|---|
singleton | 默认值,单例的,使用同一个对象 |
prototype | 多例的,创建多个对象 |
request | WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中 |
session | WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中 |
global session | WEB 项目中,应用在 Portlet 环境,如果没有 Portlet 环境那么globalSession 相当 |
1)当scope的取值为singleton时
Bean的实例化个数:1个
Bean的实例化时机:当Spring核心文件被加载时,实例化配置的Bean实例
Bean的生命周期:
- 对象创建:当应用加载,创建容器时,对象就被创建了
- 对象运行:只要容器在,对象一直活着
- 对象销毁:当应用卸载,销毁容器时,对象就被销毁了
2)当scope的取值为prototype时
Bean的实例化个数:多个
Bean的实例化时机:当调用getBean()方法时实例化Bean
- 对象创建:当使用对象时,创建新的对象实例
- 对象运行:只要对象在使用中,就一直活着
- 对象销毁:当对象长时间不用时,被 Java 的垃圾回收器回收了演示代码
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao userDao1 = (UserDao) app.getBean("userDao"); UserDao userDao2 = (UserDao) app.getBean("userDao"); System.out.println(userDao1); System.out.println(userDao2);
singleton:当Spring核心文件被加载时创建UserDaoImpl被创建 com.ctc.dao.impl.UserDaoImpl@2b662a77 com.ctc.dao.impl.UserDaoImpl@2b662a77
prototype:当get时创建UserDaoImpl被创建 UserDaoImpl被创建 com.ctc.dao.impl.UserDaoImpl@436813f3 com.ctc.dao.impl.UserDaoImpl@74fe5c40
2. Bean实例化三种方式
- 无参构造方法实例化它会根据默认无参构造方法来创建类对象,如果bean中没有默认无参构造函数,将会创建失败
<bean id="userDao" class="com.ctc.dao.impl.UserDaoImpl"></bean>
- 工厂静态方法实例化
public class StaticFactory { public static UserDao getUserDao(){ return new UserDaoImpl(); } }
<bean id="userDao" class="com.ctc.factory.StaticFactory" factory-method="getUserDao"></bean>
- 工厂实例方法实例化
public class UserServiceImpl implements UserService { public void save() { ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao userDao = (UserDao) app.getBean("userDao"); userDao.save(); } }
<bean id="factory" class="com.ctc.factory.DynamicFactory"></bean> <bean id="userDao" factory-bean="factory" factory-method="getUserDao"></bean>
3.Bean的依赖注入
概念:
依赖注入(Dependency Injection):它是 Spring 框架核心 IOC 的具体实现。
在编写程序时,通过控制反转,把对象的创建交给了 Spring,但是代码中不可能出现没有依赖的情况。IOC 解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。
那这种业务层和持久层的依赖关系,在使用 Spring 之后,就让 Spring 来维护了。简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。
依赖注入方式:
- 构造方法
- set方法
1)set方法注入
P命名空间注入本质也是set方法注入,但比起上述的set方法注入更加方便,主要体现在配置文件中,如下:
首先,需要引入P命名空间:
xmlns:p="http://www.springframework.org/schema/p"
其次,需要修改注入方式
<bean id="userService" class="com.ctc.service.impl.UserServiceImpl" p:userDao-ref="userDao"></bean>
2)构造方法注入
public class UserServiceImpl implements UserService {
public void save() {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) app.getBean("userDao");
userDao.save();
}
}
<bean id="userDao" class="com.ctc.dao.impl.UserDaoImpl">
<bean id="userService" class="com.ctc.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
依赖注入的数据类型
上面的操作,都是注入的引用Bean,处了对象的引用可以注入,普通数据类型,集合等都可以在容器中进行注入。
注入数据的三种数据类型
- 普通数据类型
- 引用数据类型
- 集合数据类型
之前的操作都是对UserDao对象的引用进行注入的,下面将以set方法注入为
例,演示普通数据类型和集合数据类型的注入
<bean id="userDao" class="com.ctc.dao.impl.UserDaoImpl">
<property name="stringList">
<list>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</list>
</property>
<property name="userMap">
<map>
<entry key="user1" value-ref="user1"></entry>
<entry key="user2" value-ref="user2"></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="p1">p</prop>
<prop key="p2">pp</prop>
<prop key="p3">ppp</prop>
</props>
</property>
</bean>
<bean id="user1" class="com.ctc.domain.User">
<property name="name" value="tom"></property>
<property name="addr" value="beijing"></property>
</bean>
<bean id="user2" class="com.ctc.domain.User">
<property name="name" value="lucy"></property>
<property name="addr" value="tianjing"></property>
</bean>
<bean id="userService" class="com.ctc.service.impl.UserServiceImpl" p:userDao-ref="userDao"></bean>
4.引入其他配置文件
实际开发中,Spring的配置内容非常多,这就导致Spring配置很繁杂且体积很大,所以,可以将部分配置拆解到其他配置文件中,而在Spring主配置文件通过import标签进行加载
<import resource="applicationContext-xxx.xml"/>
二、配置数据源
1. 数据源(连接池)的作用
- 数据源(连接池)是提高程序性能如出现的
- 事先实例化数据源,初始化部分连接资源
- 使用连接资源时从数据源中获取
- 使用完毕后将连接资源归还给数据源
常见的数据源(连接池):DBCP、C3P0、BoneCP、Druid等
2.Spring配置数据源
可以写在property中
<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="ctc20020327"></property>
</bean>
也可以加载jdbc.properties配置文件获得连接信息
首先,需要引入context命名空间和约束路径:
- 命名空间:xmlns:context="http://www.springframework.org/schema/context"
- 约束路径:http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd
<!-- 加载外部的jdbc.properties文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
三、注解开发
1.Spring原始注解
Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置文件可以简化配置,提高开发效率。
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的销毁方法 |
注意:
使用注解进行开发时,需要在applicationContext.xml中配置组件扫描,作用是指定哪个包及其子包下的Bean需要进行扫描以便识别使用注解配置的类、字段和方法。
<!-- 使用注解,需要配置组件扫描 -->
<context:component-scan base-package="com.ctc"/>
2.Spring新注解
使用上面的注解还不能全部替代xml配置文件,还需要使用注解替代的配置如下:
- 非自定义的Bean的配置:<bean>
- 加载properties文件的配置:<context:property-placeholder>
- 组件扫描的配置:<context:component-scan>
- 引入其他文件:<import>
注解 | 说明 |
---|---|
@Configuration | 用于指定当前类是一个 Spring 配置类,当创建容器时会从该类上加载注解 |
@ComponentScan | 用于指定 Spring 在初始化容器时要扫描的包。 作用和在 Spring 的 xml 配置文件中的<context:component-scan base-package="com.itheima"/>一样 |
@Bean | 方法上,标注将该方法的返回值存储到 Spring 容器中 |
@PropertySource | 用于加载.properties 文件中的配置 |
@Import | 用于导入其他配置类 |
四、Spring集成Junit
1.现存问题
在测试类中,每个测试方法都有以下两行代码:
ApplicationContext app = new ClassPathXmlApplicationContext("bean.xml");
IAccountService as = app.getBean("accountService",IAccountService.class);
这两行代码的作用是获取容器,如果不写的话,直接会提示空指针异常。所以又不能轻易删掉。
上述问题解决思路
- 让SpringJunit负责创建Spring容器,但是需要将配置文件的名称告诉它
- 将需要进行测试Bean直接在测试类中进行注入
2.Spring集成Junit步骤
- 导入spring集成Junit的坐标
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.18</version>
</dependency>
2. 使用@Runwith注解替换原来的运行期
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringJunitTest {
}
3. 使用@ContextConfiguration指定配置文件或配置类
@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration("classpath:applicationContext.xml") // xml
@ContextConfiguration(classes = {SpringCofiguration.class}) // 全注解
public class SpringJunitTest {
}
4. 使用@Autowired注入需要测试的对象
@Autowired
private UserService userService;
5. 创建测试方法进行测试
@Test
public void test1() throws SQLException {
userService.save();
System.out.println(dataSource.getConnection());
}
Comments NOTHING