IOC的应用

1. IOC

Spring最成功的是其提出的理念,而不是技术本身。它所依赖的两个核心理念,

  • 一个是控制反转(Inversion of Control,IoC),
  • 另一个是面向切面编程(Aspect Oriented Programming,AOP)。

1.1 简介

IoC是一种通过描述来生成或者获取对象的技术,而这个技术不是Spring甚至不是Java独有的。对于Java初学者更多的时候所熟悉的是使用new关键字来创建对象,而在Spring中则不是,它是通过描述来创建对象。只是Spring Boot并不建议使用XML,而是通过注解的描述生成对象。

1.2 容器的功能

Spring还提供了依赖注入的功能,使得我们能够通过描述来管理各个对象之间的关系。
为了描述上述的班级、同学和老师这3个对象关系,我们需要一个容器。在Spring中把每一个需要管理的对象称为Spring Bean(简称Bean),而Spring管理这些Bean的容器,被我们称为Spring IoC容器(或者简称IoC容器)。IoC容器需要具备两个基本的功能:

  • 通过描述管理Bean,包括发布和获取Bean;
  • 通过描述完成Bean之间的依赖关系。

2. 装配Bean

2.1 扫描装配

对于扫描装配而言使用的注解是@Component和@ComponentScan。

# @Component('')
- 是标明哪个类被扫描进入Spring IoC容器,
# @ComponentScan
- 则是标明采用何种策略去扫描装配Bean。

2.1.1 @Component

装配Bean 的名字

  • 默认类名首字母小写作为名字
  • @Component('user')

2.1.2 @ComponentScan

扫描Bean

  • 默认当前包和子包

自定义扫描包

2.2 自定义第三方Bean

作用:

​ 现实的Java的应用往往需要引入许多来自第三方的包,并且很有可能希望把第三方包的类对象也放入到Spring IoC容器中,这时@Bean注解就可以发挥作用了。

2.2.1 @Bean

  • 默认使用方法名称或者@Bean(name = “dataSource”)
  • 配合@Configuration注解使用
@Configuration
public class AppConfig {
  
    @Bean(name = "dataSource")
    public DataSource getTestDataSource() {
    	return  null;
    }

}

2.3 依赖注入

IOC对于如何进行获取,还有一个作用没有谈及,那就是Bean之间的依赖,在Spring IoC的概念中,我们称为依赖注入(Dependency Injection,DI)。

2.3.1 @Autowired

  • 根据属性的类型(by type)找到对应的Bean进行注入。
  • 用在属性,方法上面。
  • 必须是唯一的。

消除唯一性:

​ 如果对应类型的Bean不是唯一的,那么它会根据其属性名称和Bean的名称进行匹配。如果匹配得上,就会使用该Bean;如果还无法匹配,就会抛出异常。

2.3.2 消除歧义性——@Primary和@Quelifier

@Primary

  • 在类上设置为主要的,优先注入。

@Quelifier:

  • @Quelifier可以满足你的这个愿望。它的配置项value需要一个字符串去定义,它将与@Autowired组合在一起,通过类型和名称一起找到Bean。
@Autowired
@Qualifier(value = "dog")

3. 引入XML配置Bean

3.1 配置xml文件

  1. 定义POJO
package com.springboot.other.pojo;

import com.springboot.chapter3.pojo.definition.Animal;

public class Squirrel implements Animal {

	@Override
	public void use() {
		System.out.println("松鼠可以采集松果");
	}
}

  1. 写xml文件
<beans xmlns="http://www.springframework.org/schema/beans"
    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">
       <bean id="squirrel" class="com.springboot.other.pojo.Squirrel"/>
</beans>

3.2 装配Bean-@ImportResource

@ImportResource(value = {"classpath:spring-other.xml"})

4. 使用属性文件

​ 在Spring Boot中使用属性文件,可以采用其默认为我们准备的application.properties,也可以使用自定义的配置文件。

4.1 文件依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

配置文件写入

database.driverName=com.mysql.jdbc.Driver
database.url=jdbc:mysql://localhost:3306/chapter3
database.username=root
database.password=123456

4.2 读取

4.2.1 @Value

@Value("${database.driverName}")
private String driverName = null;

4.2.2 @ConfigurationProperties( “database”)

​ 注解@ConfigurationProperties中配置的字符串database,将与POJO的属性名称组成属性的全限定名去配置文件里查找,这样就能将对应的属性读入到POJO当中。

@ConfigurationProperties( "database")
public class DataBaseProperties {
  
  private String driverName = null;
  
}

4.3 使用其他配置文件

@PropertySource(value = {"classpath:jdbc.properties"},ignoreResourceNotFound = true)

5. 条件装配Bean

一个注解,一个接口

  • 接口返回Boolean值,为正加载Bean。
// 注解
@Conditional(DatabaseConditional.class)//接口 Condition
  
public class DatabaseConditional implements Condition {

	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
		Environment env = context.getEnvironment();
		return env.containsProperty("database.driverName") && env.containsProperty("database.url") 
				&& env.containsProperty("database.username") && env.containsProperty("database.password");
	}

}

6. Bean的作用域

6.1 @Scope

@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class DatabaseConditional implements Condition {
  
}

7. 使用@Profile切换开发环境

7.1 设置运行环境

JAVA_OPTS="-Dspring.profiles.active=dev"

7.2 @Profile 配置如何生效

在Spring中存在两个参数可以提供给我们配置,以修改启动Profile机制,

  • 一个是spring.profiles.active,
  • 另一个是spring.profiles.default。

​ 在这两个属性都没有配置的情况下,Spring将不会启动Profile机制,这就意味着被@Profile标注的Bean将不会被Spring装配到IoC容器中。

7.2.1 优先级

​ Spring是先判定是否存在spring.profiles.active配置后,再去查找spring.profiles.default配置的,所以spring.profiles.active的优先级要大于spring.profiles.default。

7.3 使用@Profile添加Bean

		@Bean(name = "dataSource", destroyMethod = "close")		@Profile("test")    public DataSource getTestDataSource() {        Properties props = new Properties();        props.setProperty("driver", "com.mysql.jdbc.Driver");        props.setProperty("url", "jdbc:mysql://localhost:3306/test_spring_boot");        props.setProperty("username", "root");        props.setProperty("password", "123456");        DataSource dataSource = null;        try {            dataSource = BasicDataSourceFactory.createDataSource(props);        } catch (Exception e) {            e.printStackTrace();        }        return dataSource;    }

7.4 属性配置(properties)文件

​ 在Spring Boot中还存在一个约定,假设把选项-Dspring.profiles.active配置的值记为{profile},则它会用application-{profile}.properties文件去代替原来默认的application.properties文件,

8. 使用Spring EL

@Value("#{T(System).currentTimeMillis()}")private Long initTime = null;

​ 注意,这里采用#{…}代表启用Spring表达式,它将具有运算的功能;

​ T(…)代表的是引入类;System是java.lang.*包的类,

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值