Spring程序开发步骤
- 导入Spring开发的基本包坐标(或jar包);
- 编写
DAO
接口和实现类——Bean
; - 创建Spring核心配置文件——
applicationContext.xml
; - 在Spring配置文件中配置
xxxDaoImpl
; - 使用Spring的API获取
Bean
实例——创建ApplicationContext
对象的getBean
。
Spring重点配置
<bean>
标签
<bean id="id" class="className" scope="singleton" init-method="init" destroy-method="destroy" ></bean>
id
属性:在容器中Bean实例的唯一标识,不允许重复;class
属性:要实例化的Bean的全限定名;scope
属性:Bean的作用范围,常用的是:
①singleton
——默认值,单例的,当Spring核心文件被加载时,实例化配置的Bean实例,当应用卸载,销毁容器是,对象就被销毁了;
②prototype
——多例的,当调用getBean()
方法时实例化Bean,当对象长时间不用时,被Java的垃圾回收器回收了;- 其他值:
request,session,global session
- 其他值:
- *
init-method
属性:指定类中的初始化方法名称 - *
destory-method
属性:指定类中的销毁方法名称
<property>
标签:属性注入
name
属性:属性名称value
属性:煮熟普通属性值ref
属性:注入对象引用值<list>
标签:注入list<map>
标签:注入map<proprtties>
标签<construstor-arg>
标签:有参构造注入
<import>
标签:导入其他的Spring分文件
Bean实例化方法:
- 无参构造方法(常用)
- 工厂静态方法
- 工厂动态方法
Bean依赖注入方法:
- set方法注入
- 构造方法注入
一个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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- <bean id="userDao" class="com.learningtest.dao.impl.UserDaoImpl" scope="singleton" init-method="init" destroy-method="destroy"></bean>-->
<!--静态工厂实例化-->
<!-- <bean id="userDao" class="com.learningtes.factory.StaticFactory" factory-method="getUserDao"></bean>-->
<!--动态工厂实例化-->
<!-- <bean id="factory" class="com.learningtes.factory.DynamicFactory"/>-->
<!-- <bean id="userDao" factory-bean="factory" factory-method="getUserDao"/>-->
<bean id="userDao" class="com.learningtes.dao.impl.UserDaoImpl">
<!--注入普通数据类型-->
<!-- <property name="username" value="张三"/>-->
<!-- <property name="age" value="18"/>-->
<!--注入集合数据类型-->
<property name="strList">
<list>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</list>
</property>
<property name="userMap">
<map>
<entry key="u1" value-ref="user1"/>
<entry key="u2" value-ref="user2"/>
</map>
</property>
<property name="properties">
<props>
<prop key="p1">ppp1</prop>
<prop key="p2">ppp2</prop>
<prop key="p3">ppp3</prop>
</props>
</property>
</bean>
<bean id="user1" class="com.learningtes.domain.User">
<property name="name" value="tom"/>
<property name="addr" value="beijing"/>
</bean>
<bean id="user2" class="com.learningtes.domain.User">
<property name="name" value="lucy"/>
<property name="addr" value="tianjin"/>
</bean>
<!-- <bean id="userService" class="com.learningtes.service.impl.UserServiceImpl">-->
<!-- <property name="userDao" ref="userDao"></property>-->
<!-- </bean>-->
<!-- <bean id="userService" class="com.learningtes.service.impl.UserServiceImpl" p:userDao-ref="userDao"/>-->
<bean id="userService" class="com.learningtes.service.impl.UserServiceImpl">
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>
</beans>
Spring的相关API
ApplicatopmContext
的实现类
ClassPathXmlApplicationContext
:从类的根路径下加载配置文件(推荐使用);FileSystemXmlApplicationContext
:从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置;AnnotationConfigApplicationContext
:当使用注解配置容器对象时,需要使用此类来创建spring容器,它用来读取注解。
getBean()
方法使用:
- 当参数的数据类型是字符串时,表示根据Bean的id从容器中获得Bean实例,返回Object,需要强转;当参数的数据类型是Class类型时,表示根据类型从容器中琵琶Bean实例,当容器中相同类型的Bean有多个时,则此方法会报错。
Spring配置数据源
数据源(连接池)的作用
- 数据源(连接池)是提高程序性能而出现的
- 事先实例化数据源,初始化部分连接资源
- 使用连接资源时从数据源中获取
- 使用完毕后将连接资源归还给数据源
- *常见的数据源(连接池):
DBCP
、C3P0
、BoneCP
、Druid
等
注意:当使用
mysql-connector-java-8.0.18.jar
的时候,会涉及到设置时区的问题,所以需要在url
最后加上?serverTimezone=GMT%2B8
(例:jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8)
**
抽取jdbc
配置文件(applicationContext.xml
加载jdbc.properties
配置文件获得连接信息)
- 首先需要在
applicationContext.xml
文件头部引入context
命名空间和约束路径:
//命名空间:
xmlns:context="http://www.springframework.org/schems/context"
//约束路径:
http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd
- Spring容器加载properties文件
<!--加载外部的properties文件-->
<context:property-placeholder location="classpath:xx.properties"/>
<!--配置组件扫描-->
<property name=" " value="${key}"/>
spring配置数据源测试类
public class DataSourceTest {
@Test
//测试手动创建 c3p0 数据源
public void test1() throws Exception {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8");
dataSource.setUser("root");
dataSource.setPassword("root");
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
@Test
//测试手动创建 druid 数据源
public void test2() throws SQLException {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8");
dataSource.setUsername("root");
dataSource.setPassword("root");
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
@Test
//测试手动创建c3p0数据源(加载properties配置文件)
public void test3() throws PropertyVetoException, SQLException {
//读取配置文件
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);
connection.close();
}
@Test
//测试Spring产生数据源对象
public void test4() throws SQLException {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource = app.getBean(DataSource.class);
Connection connection = dataSource.getConnection();
System.out.println(connection);
connection.close();
}
Spring注解开发
Spring原始注解:主要是替代<bean>
的配置
@Component
:使用在类上用于实例化Bean@Controller
:使用在web层类上用于实例化Bean@Service
:使用在service层类上用于实例化Bean@Repository
:使用在dao层上用于实例化Bean@Autowired
:使用在字段上用于根据类型依赖注入@Qualifier
:结合@Autowired
一起使用用于根据名称进行依赖注入@Resource
:相当于@Autowired
+@Qualifier
,按照名称进行依赖注入@Value
:注入普通属性@Scope
:标注Bean的作用范围- *
@PosConstruct
:使用在方法上标注该方法是Bean的初始化方法 - *
@PreDestory
:使用在方法上标注该方法是Bean的销毁方法
使用注解进行开发时,需要在applicationContext.xml
中配置组件扫描,作用是指定那个包及其子包下的Bean需要进行扫描以便使用注解配置类、字段和方法
Spring新注解
使用原始注解还不能全部替代
.xml
配置文件,如:
非自定义的Bean配置:<bean>
加载properties文件的配置:<context:property-plcaeholder>
组件扫描的配置:<context:component-scan>
引入其他文件:<import>
@Configuration
:用于指定当前类是一个Spring配置类,当创建容器时会从该类上加载注解;@ComponentScan
:用于指定Spring在初始化容器时要臊面的包;作用和在Spring的.xml
配置文件中的
<context:component-scan base-package="com.xxx"/>
一样;
@Bean
:使用在方法上,标注将该方法的返回值存储到Spring容器中;@PropertySource
:用于加载.properties
文件中的配置;@Import
:用于导入其他配置类。
//Spring配置类
@Configuration //标志该类是Spring的核心配置类
@ComponentScan("com.xxx") //相当于xml中的<context:component-scan base-package="com.xxx"/>
@Import(DataSourceConfiguration.class) //相当于.xml中的<import resource=""/>
public class SpringConfiguration {
}
//数据源配置类
@PropertySource("classpath:jdbc.properties") //相当于.xml中的<context:property-placeholder location="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") //spring会将当前方法的返回值以指定名称存储到spring容器中
public DataSource getDataSource() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);
return dataSource;
}
}
//Bean
@Repository("userDao")
public class UserDaoImpl implements UserDao {
public void xxx(){
System.out.println("");
}
}
@Service("userService")
@Scope("singleton")
public class UserServiceImpl implements UserService {
@Value("${jdbc.driver}")
private String driver;
//<property name="userDao" ref="userDao"></property>
//@Autowired //按照数据类型从spring容器中进行匹配
//@Qualifier("userDao") //按照id从容器中进行匹配,但是此处要结合@Autowired一起使用
@Resource(name = "userDao")
private UserDao userDao;
//使用xml进行配置市必须写,使用注解方法配置是可以不用
//public void setUserDao(UserDao userDao) {
// this.userDao = userDao;
//}
public void xxx() {
System.out.println(driver);
userDao.xxx();
}
@PostConstruct
public void init(){
System.out.println("Service对象的初始化方法");
}
@PreDestroy
public void destory(){
System.out.println("Service对象的销毁方法");
}
}
Spring集成Junit
原始Junit测试Spring的问题
在测试类中,每个测试方法都有以下两行代码:
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
IAccountService as = ac.getBean("accountService",IAccountService.class);
这两行代码的作用是获取容器,如果不写的话,直接会提示空指针异常,所以又不能轻易删掉;
解决思路
- 让SpringJunit负责创建Spring容器,但是需要将配置文件的名称告诉它;
- 将需要进行测试的Bean直接在测试类中进行注入。
Spring集成Junit步骤
- 导入spring集成Junit的坐标
- 使用
@Runwith
注解替换原来的运行期 - 使用
@ContextConfiguration
指定配置文件或配置类 - 使用
@Autowired
注入需要测试的对象 - 创建测试方法进行测试
//SpringJunit测试类
@RunWith(SpringJUnit4ClassRunner.class)
//@ContextConfiguration("classpath:applicationContext.xml")
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
@Autowired
private UserService userService;
@Autowired
private DataSource dataSource;
@Test
public void test1() throws SQLException {
userService.xxx();
System.out.println(dataSource.getConnection());
}
}