文章目录
第三方资源配置管理
管理DataSource连接池对象
管理Druid连接池
-
添加Druid连接池依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.16</version> </dependency> -
配置DruidDataSource连接池Bean对象
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/spring_db"/> <property name="username" value="root"/> <property name="password" value="root"/> </bean> -
在测试类中从ioc容器中获取连接池对象并打印
public class App {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource = (DataSource) ctx.getBean("dataSource");
System.out.println(dataSource);
}
}
管理c3p0连接池对象
查询坐标:https://mvnrepository.com/
-
添加c3p0连接池坐标
<dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> -
配置c3p0连接池Bean对象
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring_db"/> <property name="user" value="root"/> <property name="password" value="root"/> <property name="maxPoolSize" value="1000"/> </bean> -
在测试类中从IOC容器中获取连接池对象并打印
public class App {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource = (DataSource) ctx.getBean("dataSource");
System.out.println(dataSource);
}
}
加载properties属性文件
目的:就是将数据库的连接参数抽取到一个单独的文件中,与Spring配置文件解耦
基本用法
-
编写jdbc.properties文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/spring_db
jdbc.username=root
jdbc.password=root -
在applicationContext.xml中开启context命名空间,加载jdbc.properties文件
<context:property-placeholder location="jdbc.properties"/>
-
在配置连接池Bean的地方使用EL表达式获取jdbc.properties属性文件中的值
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> -
配置完成之后,运行之前的获取Druid连接池代码,可以获取到连接池对象表示配置成功
配置不加载系统属性
问题 :如果属性文件中配置的不是jdbc.username,而是username=root666,那么使用${username}获取到的不是root666,而是计算机的名称。
原因 :系统属性的优先级比我们属性文件中的高,替换了我们的username=root666。
解决:
- 换一个名称,叫jdbc.username
- 使用system-properties-mode="NEVER"属性表示不使用系统属性。
<context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/>
加载properties文件写法
- 加载多个properties文件
<context:property-placeholder location="jdbc.properties,msg.properties"/>
- 加载所有的properties文件
<context:property-placeholder location="*.properties"/>
- 加载properties文件(不包含jar包中的properties文件)
<context:property-placeholder location="classpath:*.properties"/>
- 加载properties文件(包含jar包中的properties文件)
<context:property-placeholder location="classpath*😗.properties"/>
Spring容器
Spring核心容器介绍
创建容器
- 类路径加载配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
- 文件路径加载配置文件
ApplicationContext ctx = new FileSystemXmlApplicationContext("D:\applicationContext.xml");
- 加载多个配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean1.xml", "bean2.xml");
获取bean对象
- 使用bean名称获取
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
- 使用bean名称并指定类型
BookDao bookDao = ctx.getBean("bookDao", BookDao.class);
- 使用bean类型获取
如果IOC容器中同类型的Bean对象有多个,此处获取会报错
BookDao bookDao = ctx.getBean(BookDao.class);
容器类层次结构
BeanFactory
-
类路径加载配置文件
Resource resources = new ClassPathResource("applicationContext.xml");
BeanFactory bf = new XmlBeanFactory(resources);
BookDao bookDao = bf.getBean("bookDao", BookDao.class);
bookDao.save(); -
延迟加载Bean:BeanFactory创建完毕后,所有的Bean均为延迟加载,也就是说我们调用getBean()对象时才创建Bean对象并返回给我们
Spring核心容器总结
容器相关
- BeanFactory是IoC容器的顶层接口,初始化BeanFactory对象时,加载的bean延迟加载
- ApplicationContext接口是Spring容器的核心接口,初始化时bean立即加载
- ApplicationContext接口提供基础的bean操作相关方法,通过其他接口扩展其功能
- ApplicationContext接口常用初始化类
- ClassPathXmlApplicationContext(常用)
- FileSystemXmlApplicationContext
bean相关
依赖注入相关
Spring注解开发
使用xml配置太繁琐,使用注解来简化开发
注解开发定义bean对象
基本使用
- 在applicationContext.xml中开启Spring注解包扫描
xml
<?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">
<!--扫描com.itheima包及其子包下的类中注解-->
<context:component-scan base-package="com.itheima"/>
</beans>
- 在类上使用@Component注解定义Bean
xml
//@Component定义bean
@Component("bookDao")
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ...");
}
}
补充:如果@Component注解没有使用参数指定Bean的名称,那么类名首字母小写就是Bean在IOC容器中的默认名称(前提是类名遵守大驼峰命名法),若是不遵守,则名称就是原本的类名
- 在测试类中获取Bean对象
xml
public class App {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
// BookDao bookDao = ctx.getBean(BookDao.class);
BookDao bookDao = (BookDao) ctx.getBean("bookDaoImpl");
bookDao.update();
}
@Component三个衍生注解
- @Controller:用于表现层bean定义
- @Service:用于业务层bean定义
- @Repository :用于数据层bean定义
纯注解开发模式(重点)
纯注解开发模式介绍
- Spring3.0开启了纯注解开发模式,使用Java类替代配置文件。
- Java类代替Spring核心配置文件
- @Configuration注解用于设定当前类为配置类
- @ComponentScan注解用于设定扫描路径,此注解只能添加一次,多个数据用数组形式
@ComponentScan({com.itheima.service","com.itheima.dao"})
- 加载Spring核心配置文件初始化对象切换为读取Java配置类初始化容器对象
xml
//加载配置文件初始化容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//加载配置类初始化容器
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
代码演示
- 定义配置类代替配置文件
xml
//声明当前类为Spring配置类
@Configuration
//Spring注解扫描,相当于<context:component-scan base-package="com.itheima"/>
@ComponentScan("com.itheima")
//设置bean扫描路径,多个路径书写为字符串数组格式
//@ComponentScan({"com.itheima.service","com.itheima.dao"})
public class SpringConfig {
}
- 在测试类中加载配置类,获取Bean对象并使用
java
public class AppForAnnotation {
public static void main(String[] args) {
//AnnotationConfigApplicationContext加载Spring配置类初始化Spring容器
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
System.out.println(bookDao);
//按类型获取bean
BookService bookService = ctx.getBean(BookService.class);
System.out.println(bookService);
}
}
注解开发Bean作用范围和生命周期管理
bean作用范围注解配置
- 使用**@Scope**定义bean作用范围
java
@Repository
@Scope("singleton")
public class BookDaoImpl implements BookDao {
}
bean生命周期注解配置
- 使用**@PostConstruct、@PreDestroy**定义bean生命周期
java
@Repository
@Scope("singleton")
public class BookDaoImpl implements BookDao {
public BookDaoImpl() {
System.out.println("book dao constructor ...");
}
@PostConstruct
public void init(){
System.out.println("book init ...");
}
@PreDestroy
public void destroy(){
System.out.println("book destory ...");
}
}
注:@PostConstruct和@PreDestroy注解是jdk中提供的注解,从jdk9开始,jdk中的javax.annotation包被移除了,也就是说这两个注解就用不了了,可以额外导入一下依赖解决这个问题。
java
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
注解开发依赖注入
使用@Autowired注解开启自动装配模式(按类型)
xml
@Service
public class BookServiceImpl implements BookService {
//@Autowired:注入引用类型,自动装配模式,默认按类型装配
@Autowired
private BookDao bookDao;
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
说明:不管是使用配置文件还是配置类,都必须进行对应的Spring注解包扫描才可以使用。@Autowired默认按照类型自动装配,如果IOC容器中同类的Bean有多个,那么默认按照变量名和Bean的名称匹配,建议使用@Qualifier注解指定要装配的bean名称
注 :自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法。
使用@Qualifier注解指定要装配的bean名称
解决IOC容器中同类型Bean有多个装配哪一个的问题
xml
@Service
public class BookServiceImpl implements BookService {
//@Autowired:注入引用类型,自动装配模式,默认按类型装配
@Autowired
//@Qualifier:自动装配bean时按bean名称装配
@Qualifier("bookDao")
private BookDao bookDao;
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
注 :@Qualifier注解无法单独使用,必须配合@Autowired注解使用
使用@Value实现简单类型注入
xml
@Repository("bookDao")
public class BookDaoImpl implements BookDao {
//@Value:注入简单类型(无需提供set方法)
@Value("abc")
private String name;
public void save() {
System.out.println("book dao save ..." + name);
}
}
也可以从属性文件中读取,需要在配置类或配置文件中加载属性文件@Value("${name}")
xml
@Configuration
@ComponentScan("com.itheima")
//@PropertySource加载properties配置文件
@PropertySource({"classpath:jdbc.properties"}) //{}可以省略不写
public class SpringConfig {
}
注 :@PropertySource()中加载多文件请使用数组格式配置,不允许使用通配符*
注解开发管理第三方Bean(重点)
单独定义配置类
xml
public class JdbcConfig {
//@Bean:表示当前方法的返回值是一个bean对象,添加到IOC容器中
@Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/spring_db");
ds.setUsername("root");
ds.setPassword("root");
return ds;
}
}
将独立的配置类加载到核心配置类中
方式1 :@Import注解导入式
xml
@Configuration
@ComponentScan("com.itheima")
//@Import:导入配置信息
@Import({JdbcConfig.class})
public class SpringConfig {
}
方式2 :@ComponentScan扫描式
xml
@Configuration
@ComponentScan({"com.itheima.config","com.itheima.service","com.itheima.dao"}) //只要com.itheima.config包扫到了就行,三个包可以合并写成com.itheima
public class SpringConfig {
}
注 :用方式2需要在独立的配置类中添加@Configuratoin注解
注解开发为第三方Bean注入资源(重点)
简单类型依赖注入
xml
public class JdbcConfig {
//1.定义一个方法获得要管理的对象
@Value("com.mysql.jdbc.Driver")
private String driver;
@Value("jdbc:mysql://localhost:3306/spring_db")
private String url;
@Value("root")
private String userName;
@Value("root")
private String password;
//2.@Bean:表示当前方法的返回值是一个bean对象,添加到IOC容器中
@Bean
public DataSource dataSource(){
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(password);
return ds;
}
}
说明 :如果@Value()中使用了EL表达式读取properties属性文件中的内容,那么就需要加载properties属性文件。
引用类型依赖注入
xml
//Spring会自动从IOC容器中找到BookDao对象赋值给参数bookDao变量,如果没有就会报错。
@Bean
public DataSource dataSource(BookDao bookDao){
System.out.println(bookDao);
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(userName);
ds.setPassword(password);
return ds;
}
说明 :引用类型注入只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象