Spring基础
xml配置开发
1 bean的基本配置
1.1 id与class
id与class时基本配置中的基本
- 格式
1 | <bean id="" class=""/> |
属性
- id:使用容器时可以通过id值获取到对应的bean,一个容器中id值唯一
- class:配置的bean的全路径类名
示例
1 | <bean id = "selectbao" class = "dao.imp.selectDaoImpl"/> |
1.2 名字name
就是为bean定义别名,可以定义多个。使用空格、逗号或分号隔开
- 格式
1 | <bean id="" naem="" class=""/> |
- 示例
1 | <bean id = "selectbao" name="one two three" class = "dao.imp.selectDaoImpl"/> |
1.3 作用范围scope
- 格式
1 | <bean id="" naem="" class=""/ scope=""> |
- 可选项
- singleton:单例(默认值)
- prototype:非单例
- 实例
1 | <bean id="" naem="" class=""/ scope="prototype"> |
单例
单例的意思是在Spring的IOC容器中只会有该类的一个对象,避免了对象的频繁创建与销毁,达到了bean对象的复用,性能高
2 bean实例化
2.1 构造方法实例化
通过无参构造方法实例化。也是最为简单和现在最为常用的方法
1 | public interface dao1 { |
1 | public class dao1Impl implements dao1 { |
配置文件
1 | <bean id="dao1" class="dao.Impl.dao1Impl"/> |
2.2 静态工厂实例化
1 | public interface dao1 { |
1 | public class dao1Impl implements dao1 { |
工厂java,用一个工厂java,用一个静态方法返回一个dao1Impl对象。这是早些时间常用的方法。方法返回一个dao1Impl对象。这是早些时间常用的方法。
1 | public class dao1Factory { |
配置文件
1 | <bean id="dao1" class="dao1Factory" factory-method="getDao1Impl"/> |
class:工厂类的类全名
factory-mehod:具体工厂类中创建对象的方法名
2.3 非静态工厂实例化
1 | public interface dao1 { |
1 | public class dao1Impl implements dao1 { |
工厂java,用一个非静态方法返回一个dao1Impl对象。这是早些时间常用的方法。
1 | public class dao1Factory { |
配置文件
1 | <bean id="dao1Factory" class="dao1Factory"/> |
2.4 FactoryBean
实例工厂实例化的方式就已经介绍完了,配置的过程还是比较复杂,所以Spring为了简化这种配置方式就提供了一种叫FactoryBean
的方式来简化开发。
下面这一部分还是不变
1 | public interface dao1 { |
1 | public class dao1Impl implements dao1 { |
在工厂文件中就有所变化了,要实现实现FactoryBean接口,重写接口的方法
1 | public class dao1Factory implements FactoryBean { |
配置文件
1 | <bean id="dao1" class="dao1Factory"/> |
接口FactoryBean中有三个方法。分别是:
1 | T getObject() throws Exception; |
方法一:getObject(),被重写后,在方法中进行对象的创建并返回
方法二:getObjectType(),被重写后,主要返回的是被创建类的Class对象
方法三:没有被重写,因为它已经给了默认值,从方法名中可以看出其作用是设置对象是否为单例,默认true。
3 bean的生命周期
bean对象从创建到销毁的整体过程
我们在bean对象对应的类中分别添加两个方法,方法名任意
在配置文件中添加对应的属性参数名为对应的方法名,标签如下:
1 | init-method #初始化方法 |
例子如下
1 | <bean id="dao1" class="dao.impl.dao1Impl" init-method="init" destroy-method="destory"/> |
创建实例化工厂对象,对应的是第一行配置
调用对象中的方法来创建bean,对应的是第二行配置
- factory-bean:工厂的实例对象
factory-method:工厂对象中的具体创建对象的方法名
4 依赖注入
4.1 setter注入
通过set方法作为接口,向bean中注入数据。所以在bean对应的类中就一定要有对应的set方法
4.1.1 引用数据
引用数据就是在Spring中也配置了的对象。
如下,就是注入配置文件中的其他bean。配置配置文件中的bean得用ref标签。
1 | public class dao1Impl implements dao1 { |
1 | public class dao2Impl implements dao2 { |
1 | <bean id="dao1" class="dao.Impl.dao1Impl"/> |
4.1.2 数组
1 | <property name="array"> |
4.1.3 LIst
1 | <property name="list"> |
4.1.4 Set
1 | <property name="set"> |
4.1.5 Map
1 | <property name="map"> |
4.1.6 Properties
1 | <property name="properties"> |
4.2 构造器注入
与setter注入类似,不过接口换为带参构造函数。参数就是被注入的数据。
4.2.1 引用数据
1 | public class dao1Impl implements dao1 { |
1 | public class dao2Impl implements dao2 { |
1 | <bean id="dao1" class="dao.Impl.dao1Impl"/> |
4.1.2 数组
1 | <constructor-arg name="array"> |
4.2.3 List
1 | <constructor-arg name="list"> |
4.2.4 Set
1 | <constructor-arg name="set"> |
4.2.5 Map
1 | <constructor-arg name="map"> |
4.2.6 Properties
1 | <constructor-arg name="properties"> |
5 自动装配
自动装配就是IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean。
常用方式:
- 按类型(bytype)(常用)
- 按名称(byname)
- 按构造方法
- 不启用自动装配
使用方法:
相当于替换了property,用智能的方式自动填入
使用autowire属性
1 | bean id="dao1" class="dao.Impl.dao1Impl" autowire="byName"/> |
注意事项:
- 需要注入属性的类中对应属性的setter方法不能省略
- 被注入的对象必须要被Spring的IOC容器管理
- 按照类型在Spring的IOC容器中如果找到多个对象,会报
NoUniqueBeanDefinitionException
- 自动装配用于引用类型依赖注入,不能对简单类型进行操作
- 使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用
- 使用按名称装配时(byName)必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
- 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效
6 配置管理第三方bean
例子:实现Druid管理
6.1 导入druid依赖
1 | <dependency> |
6.2 配置第三方bean
1 | <bean id="druid" class="com.alibaba.druid.pool.DruidDataSource"> |
- driverClassName:数据库驱动
- url:数据库连接地址
- username:数据库连接用户名
- password:数据库连接密码
- 数据库连接的四要素要和自己使用的数据库信息一致。
不同第三方bean,在配置bean时。属性名可能不一样,但在idea中均有提示。
是通过setter注入的相关属性,所以在bean配置中使用了property
7 加载Properties文件
7.1 开启context命名空间
1 |
|
7.2 加载properties文件
1 | <context:property-placeholder location="文件名" system-properties-mode="NEVER"/> |
- syetem-properties-mode=”NEVER”是为了解决
<context:property-placeholder/>
标签会加载系统的环境变量,而且环境变量的值会被优先加载的问题。
7.3 获取数据
使用EL表达式获取properties文件中的数据
1 | ${key} |
注意:location配置
1 | <!--方式一 --> |
说明:
- 方式一:可以实现,如果配置文件多的话,每个都需要配置
- 方式二:
*.properties
代表所有以properties结尾的文件都会被加载,可以解决方式一的问题,但是不标准 - 方式三:标准的写法,
classpath:
代表的是从根路径下开始查找,但是只能查询当前项目的根路径 - 方式四:不仅可以加载当前项目还可以加载当前项目所依赖的所有项目的根路径下的properties配置文件
8 核心容器
8.1 容器的创建方法
方式一:ApplicationContext创建。通过配置文件名称创建
1
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
方式二:通过FileSystemXmlApplicationContext创建。通过文件的绝对路径进行创建。
1
ApplicationContext ctx = new FileSystemXmlApplicationContext("D:\\code\\spring\\src\\main\\resources\\applicationContext.xml");
这种方式虽能实现,但是当项目的位置发生变化后,代码也需要跟着改,耦合度较高,不推荐使用。
8.2 Bean的三种获取方法
通过bean的id获取
1
dao1Impl dao1 = (dao1Impl) app.getBean("dao1");
通过类型获取
1
dao1Impl dao1 = (dao1Impl) app.getBean(dao1Impl.class);
8.2 BeanFactory
使用BeanFactory来创建IOC容器的具体实现方式为:
1 | public class AppForBeanFactory { |
BeanFactory与ApplicationContext的区别
BeanFactory是延迟加载,只有在获取bean对象的时候才会去创建
ApplicationContext是立即加载,容器加载的时候就会创建bean对象
ApplicationContext要想成为延迟加载,只需要按照如下方式进行配置
1
<bean id="dao1" class=".dao.impl.dao1Impl" lazy-init="true"/>
注解开发
1 获取容器
1.1 创建配置类
在配置类上添加@Configuration
注解,将其标识为一个配置类,替换applicationContext.xml
在配置类上添加包扫描注解@ComponentScan
,用于扫描对应的java包。
1 |
|
@ComponentScan注解用于设定扫描路径,此注解只能添加一次,多个数据请用数组格式
1
小结
名称 | @Configuration |
---|---|
类型 | 类注解 |
位置 | 类定义上方 |
作用 | 设置该类为spring配置类 |
属性 | value(默认):定义bean的id |
名称 | @ComponentScan |
---|---|
类型 | 类注解 |
位置 | 类定义上方 |
作用 | 设置spring配置类扫描路径,用于加载使用注解格式定义的bean |
属性 | value(默认):扫描路径,此路径可以逐层向下扫描 |
1.2 加载容器
1 | ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfig.class);` |
2 Bean配置
2.1 Bean注明
名称 | @Component/@Controller/@Service/@Repository |
---|---|
类型 | 类注解 |
位置 | 类定义上方 |
作用 | 设置该类为spring管理的bean |
属性 | value(默认):定义bean的id |
- @Component:任何地方都能使用
- @Controller:用于web层
- @Service:用于服务层
- @Repository:用于dao层
2.2 Bean作用范围
名称 | @Scope |
---|---|
类型 | 类注解 |
位置 | 类定义上方 |
作用 | 设置该类创建对象的作用范围 可用于设置创建出的bean是否为单例对象 |
属性 | value(默认):定义bean作用范围, ==默认值singleton(单例),可选值prototype(非单例)== |
2.3 Bean生命周期
@PostConstruct
名称 | @PostConstruct |
---|---|
类型 | 方法注解 |
位置 | 方法上 |
作用 | 设置该方法为初始化方法 |
属性 | 无 |
@PreDestroy
名称 | @PreDestroy |
---|---|
类型 | 方法注解 |
位置 | 方法上 |
作用 | 设置该方法为销毁方法 |
属性 | 无 |
3 依赖注入
无论什么数据注入都可以不用写setter方法
3.1 引用类型注入
名称 | @Autowired |
---|---|
类型 | 属性注解 或 方法注解(了解) 或 方法形参注解(了解) |
位置 | 属性定义上方 或 标准set方法上方 或 类set方法上方 或 方法形参前面 |
作用 | 为引用类型属性设置值 |
属性 | required:true/false,定义该属性是否允许为null |
@Autowired是按照类型注入,那么对应到dao1接口如果有多个实现类,就会报错。这时我们就只能加上@Qualifier按名称注入
名称 | @Qualifier |
---|---|
类型 | 属性注解 或 方法注解(了解) |
位置 | 属性定义上方 或 标准set方法上方 或 类set方法上方 |
作用 | 为引用类型属性指定注入的beanId |
属性 | value(默认):设置注入的beanId |
@Qualifier不能独立使用,必须和@Autowired一起使用
3.2 普通数据注入
名称 | @Value |
---|---|
类型 | 属性注解 或 方法注解(了解) |
位置 | 属性定义上方 或 标准set方法上方 或 类set方法上方 |
作用 | 为 基本数据类型 或 字符串类型 属性设置值 |
属性 | value(默认):要注入的属性值 |
3.3 Properties注入
注解加载properties配置文件
1
2
3
4
5
public class SpringConfig {
}名称 @PropertySource 类型 类注解 位置 类定义上方 作用 加载properties文件中的属性值 属性 value(默认):设置加载的properties文件对应的文件名或文件名组成的数组 使用@Value和EL表达式读取配置文件中的内容
1
@Value("${name}")
4 管理第三方bean
4.1 配置类中添加
在配置类中添加一个方法,该方法的返回值就是要创建的Bean对象类型。并用@Bean注明
1 |
|
名称 | @Bean |
---|---|
类型 | 方法注解 |
位置 | 方法定义上方 |
作用 | 设置该方法的返回值作为spring管理的bean |
属性 | value(默认):定义bean的id |
4.2 引入外部外部配置类
4.2.1 使用包扫描
1 |
|
将jdbConfig类要放入config包中
4.2.2 @Import
引入
1 |
|
- @Import参数需要的是一个数组,可以引入多个配置类。
- @Import注解在配置类中只能写一次
- @Import注解引入的是类的类型
名称 | @Import |
---|---|
类型 | 类注解 |
位置 | 类定义上方 |
作用 | 导入配置类 |
属性 | value(默认):定义导入的配置类类名, 当配置类有多个时使用数组格式一次性导入多个配置类 |
总结对比
功能 | xml配置 | 注解 |
---|---|---|
定义bean | bean标签 id属性 class属性 |
@Component @Controller @Service @Repository @ComponentScan |
设置依赖注入 | setter输入(set方法) 构造器注入(构造方法) 自动装配 |
@Autowired @Qualifier @Value |
配置第三方bean | bean标签 静态工厂 实例工厂 FactoryBean |
@Bean |
作用范围 | scope属性 | @Scope |
生命周期 | 标准接口 init-method destroy-method |
@PostConstructor @PreDestroy |