怎么理解Spring IOC——适合初学者

目录

Spring框架的核心         IOC 和 AOP

今天着重讲解IOC      IOC: 控制反转 inverse of controller

1.显式配置Bean  

2.隐式配置Bean

注意事项

3.Bean的作用域

那么如何修改Bean的作用域呢?

4.依赖注入

注意:


Spring框架的核心
         IOC 和 AOP

今天着重讲解IOC      IOC: 控制反转 inverse of controller
 

        在接触SpringIOC之前,我们在创建对象时,是哪里使用哪里创建,需要一个创建一个,将来可能创建很多的对象。例如:

T t = new T();    t.xx //调用属性和方法等
T t1 = new T();
T t2 = new T();

        这时的对象创建权在我们自己手里,你什么时候想创建,自己去创建。而用了Spring之后呢,你无需再自己创建对象,而是向Spring去拿,对象均已经由Spring框架帮你创建好了,若要使用,直接 从Spring容器获取对象即可。容器概念————容器是用来保存东西的。那么保存什么东西呢?保存着你整个项目里面,所有类的对象。每一个类的对象都会保存进来。是Spring帮你创建好的。可能说到这里,大家还是一头雾水...我们后续举例说明。

        我们首先来看下怎么将类交由Spring来管理。这里可以理解为通知Spring来管理。通知的方式方法如下:

1.显式配置Bean  

        通过@Bean 注解完成的,但是 @Bean 注解必然是作用于配置类中的 ,@Bean 注解是作用于方法上方的,Bean就是Bean对象,Spring中对象就叫做Bean对象。
        配置类:是Spring 框架核心的一个类,通过注解 @Configuration 来表示(如果注解没有学习的同学,建议先去了解下Java中关于注解的介绍)
@Configuration 
    public class ExplicitConfig{ 
@Bean 
    public T t(){ return new T(); }
@Bean 
    public A a(){ return new A(); } 
}
//这两个类不再单独书写,下面表示已创建这两个类
class T{} 

class A{}
Spring 管理 Bean 的机制:
        1. 加载配置文件,配置文件加载完成,得到 Spring 容器,所有的 Bean 实例创建完成。
那么这时我们的T  和  A  这两个类就已经交给Spring去管理了,这里注意@Bean是作用在方法上方的,方法的返回值就是 分别返回一个T 和 A的对象。
Bean对象的获取:我们在Test类中获取上下文对象ApplicationContext,这里上下文对象大家可以理解为,它是维护那些Bean对象的一个高级接口,就是它里面有很多的方法可以供我们去打点调用。
public class ExplicitTest {
    public static void main(String[] args) {
    ApplicationContext context = SpringApplication.run(ExplicitConfig.class);
}
1.
显式配置中, BeanId 取决于方法名,方法名即为 BeanId
/*1. 根据BeanId获取
getBean(String beanId) - Object*/
T t = (T)context.getBean("t")

因为getBean方法返回的是一个Object对象,所以我们要强转为T对象。

2.

/*2. 根据BeanId,并指定类型获取 getBean(String beanId,Class<T>) - T*/
T t = context.getBean("t",T.class)

这里由于指定了类型 所以不再需要强转.

3.

/*3. 根据类型获取 getBean(Class<T>) -- T 
注意:根据类型获取必须要求该类型的实例只有一个*/
T t = context.getBean(T.class)
注意 : 根据类型获取必须要求该类型的实例只有一个,也就是只有这一种T类。.class 不懂的同学可以去看映射相关内容。
        还有一种参数注入,由于较为复杂不过多演示。
在配置类中显示配置 Bean 的方法中,可以给出指定类型的参数, Spring 在调用添加了
@Bean 注解的方式时,会自动根据参数类型找到匹配的 Bean 对象,并将其注入

2.隐式配置Bean

        
        1. 在类的上方添加组件类注解 - @Component
        2. 在配置类上方添加注解 @ComponentScan( 指定包 ) ,加载配置类时会到指定包下进行组件扫描,例如:
@Configuration
@ComponentScan("com.example.springioc.implicit")
public class ImplicitConfig {

}

        同时,我们还要在 期望交给Spring管理的类上方加上组件类的注解,

@Componnent 通用组件注解
@Controller 控制器组件
@Service 业务层组件
@Repository 持久层组件  等等   这些注解没有本质功能的区别,但是由于见名知意,可以更好的让我们理解这个类所在的是哪个模块对应MVC中的哪些业务。例如:
@Controller("t")
public class TController {
    @Autowired
    public TMapper tMapper;

隐式配置中的BeanId,默认根据类名得知BeanId

        - 类名首字母大写,第二个字母小写, beanId 为首字母小写的名称
        - 否则, beanId 为类全名
        可以自定义beanId ,在注解中添加属性值
        如@Component("a")
public class ImplicitTest {
    public static void main(String[] args) {
     ApplicationContext context = SpringApplication.run(ImplicitConfig.class);
      StudentController controller = context.getBean("t",TController.class);

注意事项

@ComponentScan 给定的包越精确越好,范围太大,启动速度慢
显式配置和隐式配置的使用建议 -- 建议混合使用
自己写的类 -- 隐式配置
第三方的类,向交给 Spring 管理 -- 显示配置

3.Bean的作用域

Spring 框架中,所有Bean的作用域默认都是单例的(singleton)
单例:某个类的实例在应用程序只有一个
作用域:
1. singleton -- 单例
2. prototype -- 原型 即每次从Spring 容器获取某个 Bean ,每次均返回新的实例
3. session -- 每个 session 对象均创建一个新的实例
4. request -- 每次请求均创建一个新的实例

那么如何修改Bean的作用域呢?

通过注解 @Scope("....") 来修改,配置 Bean 方式不同,作用的位置不同。
- 显式配置 Bean
@Bean 作用在方法上方配置
用法:
@Bean
@Scope("prototype")
public UserController userController(UserMapper userMapper){
return new UserController(userMapper);
}
- 隐式配置 Bean
@Component 作用在类的上方
@Controller("t")
@Scope(("prototype")
public class TController {
    @Autowired
    public TMapper tMapper;}

4.依赖注入

@Autowired 注解
Spring 框架提供的注解,默认根据类型注入对象
注入方式有 3 种:
1. 构造方法注入
- 注意 : 若构造方法只有一个,则该注解可选
StudentService studentService;
 @Autowired
public PersonController(StudentService studentService){
        this.studentService = studentService;
        System.out.println("PersonController构造注入。。。。。。");
        System.out.println(personService);  //查看字段注入是否完成
    }

2. setter 注入 /set 方法注入
WorkerService workerService;
    @Autowired
    public void setWorkerService(WorkerService workerService){
        System.out.println(personService);  //字段注入的值
        this.workerService = workerService;
        System.out.println("PersonController通过setter注入。。。。。");
    }

3. 字段注入(用的最多!!!)
 @Autowired
    PersonService personService;

注意事项

1.若注入的依赖项不存在,会发生什么?
Spring 容器启动失败,但是若存在这样的需求(不论依赖项是否存在,均要实例化 Bean ,此
时可以使用属性 required=false ),该属性的作用:仅当依赖项存在,才注入,若不存在,
不注入
2.若注入的类型对应的依赖项有多个,又会发生什么?

若注入的类型对应的依赖项存在多个,此时会产生歧义,启动 Spring容器直接报错
@Autowired 产生歧义的解决办法:
1. 使用 @Qualififier 指定注入的 beanId
若使用 @Autowired 注入时产生了歧义,若有 @Qualififier ,则根据给定的 beanId 进行注
入;若没有 @Qualififier, 此时会自动根据 beanid 进行查找。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Leon_coding

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值