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
2
3
public interface dao1 {
void save();
}
1
2
3
4
5
6
public class dao1Impl implements dao1 {
@Override
public void save() {
System.out.println("hello");
}
}

配置文件

1
<bean id="dao1" class="dao.Impl.dao1Impl"/>

2.2 静态工厂实例化

1
2
3
public interface dao1 {
void save();
}
1
2
3
4
5
6
public class dao1Impl implements dao1 {
@Override
public void save() {
System.out.println("hello");
}
}

工厂java,用一个工厂java,用一个静态方法返回一个dao1Impl对象。这是早些时间常用的方法。方法返回一个dao1Impl对象。这是早些时间常用的方法。

1
2
3
4
5
public class dao1Factory {
public static dao1Impl getDao1Impl(){
return new dao1Impl();
}
}

配置文件

1
<bean id="dao1" class="dao1Factory" factory-method="getDao1Impl"/>
  • class:工厂类的类全名

  • factory-mehod:具体工厂类中创建对象的方法名

2.3 非静态工厂实例化

1
2
3
public interface dao1 {
void save();
}
1
2
3
4
5
6
public class dao1Impl implements dao1 {
@Override
public void save() {
System.out.println("hello");
}
}

工厂java,用一个非静态方法返回一个dao1Impl对象。这是早些时间常用的方法。

1
2
3
4
5
public class dao1Factory {
public dao1Impl getDao1Impl(){
return new dao1Impl();
}
}

配置文件

1
2
<bean id="dao1Factory" class="dao1Factory"/>
<bean id="dao1" factory-bean="dao1Factory" factory-method="getDao1Impl"/>

2.4 FactoryBean

实例工厂实例化的方式就已经介绍完了,配置的过程还是比较复杂,所以Spring为了简化这种配置方式就提供了一种叫FactoryBean的方式来简化开发。

下面这一部分还是不变

1
2
3
public interface dao1 {
void save();
}
1
2
3
4
5
6
public class dao1Impl implements dao1 {
@Override
public void save() {
System.out.println("hello");
}
}

在工厂文件中就有所变化了,要实现实现FactoryBean接口,重写接口的方法

1
2
3
4
5
6
7
8
9
10
11
12
public class dao1Factory implements FactoryBean {

@Override
public dao1Impl getObject() throws Exception {
return new dao1Impl();
}

@Override
public Class<?> getObjectType() {
return dao1Impl.class;
}
}

配置文件

1
<bean id="dao1" class="dao1Factory"/>

接口FactoryBean中有三个方法。分别是:

1
2
3
4
5
6
7
T getObject() throws Exception;

Class<?> getObjectType();

default boolean isSingleton() {
return true;
}
  • 方法一:getObject(),被重写后,在方法中进行对象的创建并返回

  • 方法二:getObjectType(),被重写后,主要返回的是被创建类的Class对象

  • 方法三:没有被重写,因为它已经给了默认值,从方法名中可以看出其作用是设置对象是否为单例,默认true。

3 bean的生命周期

bean对象从创建到销毁的整体过程

我们在bean对象对应的类中分别添加两个方法,方法名任意

在配置文件中添加对应的属性参数名为对应的方法名,标签如下:

1
2
init-method			#初始化方法
destroy-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
2
3
4
5
6
public class dao1Impl implements dao1 {
@Override
public void save() {
System.out.println("hello");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
public class dao2Impl implements dao2 {
private dao1Impl dao1;

public void setDao1(dao1Impl dao1) {
this.dao1 = dao1;
}

@Override
public void save() {
dao1.save();
System.out.println("Spring");
}
}
1
2
3
4
<bean id="dao1" class="dao.Impl.dao1Impl"/>
<bean id="dao2" class="dao.Impl.dao2Impl">
<property name="dao1" ref="dao1"/>
</bean>

4.1.2 数组

1
2
3
4
5
6
7
<property name="array">
<array>
<value>值1</value>
<value>值2</value>
<value>值3</value>
</array>
</property>

4.1.3 LIst

1
2
3
4
5
6
7
<property name="list">
<list>
<value>值1</value>
<value>值2</value>
<value>值3</value>
</list>
</property>

4.1.4 Set

1
2
3
4
5
6
7
<property name="set">
<set>
<value>值1</value>
<value>值2</value>
<value>值3</value>
</set>
</property>

4.1.5 Map

1
2
3
4
5
6
7
<property name="map">
<map>
<entry key="键1" value="值1"/>
<entry key="键3" value="值2"/>
<entry key="键3" value="值3"/>
</map>
</property>

4.1.6 Properties

1
2
3
4
5
6
7
<property name="properties">
<props>
<prop key="键1">值1</prop>
<prop key="键2">值3</prop>
<prop key="键3">值3</prop>
</props>
</property>

4.2 构造器注入

与setter注入类似,不过接口换为带参构造函数。参数就是被注入的数据。

4.2.1 引用数据

1
2
3
4
5
6
public class dao1Impl implements dao1 {
@Override
public void save() {
System.out.println("hello");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
public class dao2Impl implements dao2 {
private dao1Impl dao1;

public dao2Impl(dao1Impl dao1) {
this.dao1 = dao1;
}

@Override
public void save() {
dao1.save();
System.out.println("Spring");
}
}
1
2
3
4
<bean id="dao1" class="dao.Impl.dao1Impl"/>
<bean id="dao2" class="dao.Impl.dao2Impl">
<constructor-arg name="dao1" ref="dao1"/>
</bean>

4.1.2 数组

1
2
3
4
5
6
7
<constructor-arg name="array">
<array>
<value>值1</value>
<value>值2</value>
<value>值3</value>
</arary>
</constructor-arg>

4.2.3 List

1
2
3
4
5
6
7
<constructor-arg name="list">
<list>
<value>值1</value>
<value>值2</value>
<value>值3</value>
</list>
</constructor-arg>

4.2.4 Set

1
2
3
4
5
6
7
<constructor-arg name="set">
<set>
<value>值1</value>
<value>值2</value>
<value>值3</value>
</set>
</constructor-arg>

4.2.5 Map

1
2
3
4
5
6
7
<constructor-arg name="map">
<map>
<entry key="键1" value="值1"/>
<entry key="键3" value="值2"/>
<entry key="键3" value="值3"/>
</map>
</constructor-arg>

4.2.6 Properties

1
2
3
4
5
6
7
<constructor-arg name="properties">
<props>
<prop key="键1">值1</prop>
<prop key="键2">值3</prop>
<prop key="键3">值3</prop>
</props>
</constructor-arg>

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
2
3
4
5
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>

6.2 配置第三方bean

1
2
3
4
5
6
<bean id="druid" 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>
  • driverClassName:数据库驱动
  • url:数据库连接地址
  • username:数据库连接用户名
  • password:数据库连接密码
  • 数据库连接的四要素要和自己使用的数据库信息一致。

不同第三方bean,在配置bean时。属性名可能不一样,但在idea中均有提示。

是通过setter注入的相关属性,所以在bean配置中使用了property

7 加载Properties文件

7.1 开启context命名空间

1
2
3
4
5
6
7
8
9
10
<?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">
</beans>

7.2 加载properties文件

1
<context:property-placeholder location="文件名" system-properties-mode="NEVER"/>
  1. syetem-properties-mode=”NEVER”是为了解决<context:property-placeholder/>标签会加载系统的环境变量,而且环境变量的值会被优先加载的问题。

7.3 获取数据

使用EL表达式获取properties文件中的数据

1
${key}

注意:location配置

1
2
3
4
5
6
7
8
<!--方式一 -->
<context:property-placeholder location="jdbc.properties,jdbc2.properties" system-properties-mode="NEVER"/>
<!--方式二-->
<context:property-placeholder location="*.properties" system-properties-mode="NEVER"/>
<!--方式三 -->
<context:property-placeholder location="classpath:*.properties" system-properties-mode="NEVER"/>
<!--方式四-->
<context:property-placeholder location="classpath*:*.properties" system-properties-mode="NEVER"/>

说明:

  • 方式一:可以实现,如果配置文件多的话,每个都需要配置
  • 方式二:*.properties代表所有以properties结尾的文件都会被加载,可以解决方式一的问题,但是不标准
  • 方式三:标准的写法,classpath:代表的是从根路径下开始查找,但是只能查询当前项目的根路径
  • 方式四:不仅可以加载当前项目还可以加载当前项目所依赖的所有项目的根路径下的properties配置文件

8 核心容器

8.1 容器的创建方法

  1. 方式一:ApplicationContext创建。通过配置文件名称创建

    1
    ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
  2. 方式二:通过FileSystemXmlApplicationContext创建。通过文件的绝对路径进行创建。

    1
    ApplicationContext ctx = new FileSystemXmlApplicationContext("D:\\code\\spring\\src\\main\\resources\\applicationContext.xml"); 

    这种方式虽能实现,但是当项目的位置发生变化后,代码也需要跟着改,耦合度较高,不推荐使用。

8.2 Bean的三种获取方法

  1. 通过bean的id获取

    1
    dao1Impl dao1 = (dao1Impl) app.getBean("dao1");
  2. 通过类型获取

    1
    dao1Impl dao1 = (dao1Impl) app.getBean(dao1Impl.class);

8.2 BeanFactory

使用BeanFactory来创建IOC容器的具体实现方式为:

1
2
3
4
5
6
7
8
public class AppForBeanFactory {
public static void main(String[] args) {
Resource resources = new ClassPathResource("applicationContext.xml");
BeanFactory bf = new XmlBeanFactory(resources);
dao1Impl dao1 = bf.getBean("dao1");
dao1.save();
}
}

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
2
3
4
@Configuration
@ComponentScan("dao")
public class SpringConfig {
}
  • @ComponentScan注解用于设定扫描路径,此注解只能添加一次,多个数据请用数组格式

    1
    @ComponentScan({"service","dao","web"})
  • 小结

名称 @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注入

  1. 注解加载properties配置文件

    1
    2
    3
    4
    5
    @Configuration
    @ComponentScan("dao")
    @PropertySource("jdbc.properties")
    public class SpringConfig {
    }
    名称 @PropertySource
    类型 类注解
    位置 类定义上方
    作用 加载properties文件中的属性值
    属性 value(默认):设置加载的properties文件对应的文件名或文件名组成的数组
  2. 使用@Value和EL表达式读取配置文件中的内容

    1
    @Value("${name}")

4 管理第三方bean

4.1 配置类中添加

在配置类中添加一个方法,该方法的返回值就是要创建的Bean对象类型。并用@Bean注明

1
2
3
4
5
6
7
8
9
10
11
12
@Configuration
public class SpringConfig {
@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;
}
}
名称 @Bean
类型 方法注解
位置 方法定义上方
作用 设置该方法的返回值作为spring管理的bean
属性 value(默认):定义bean的id

4.2 引入外部外部配置类

4.2.1 使用包扫描

1
2
3
@Configuration
@ComponentScan("config")
public class SpringConfig {}

将jdbConfig类要放入config包中

4.2.2 @Import引入

1
2
3
4
@Configuration
//@ComponentScan("com.itheima.config")
@Import({JdbcConfig.class})
public class SpringConfig {}
  • @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

如果有什么,可以通过下面的邮箱和我联系!!!

img