Spring IOC 学习笔记

本文深入探讨了Spring框架中IOC容器的基本概念与使用方法,包括Bean的注册与注入方式、@Autowired与@Resource的区别及工作原理、@Qualifier的使用场景与扩展方法等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring IOC 学习笔记

Bean

<bean id="" class=""></bean>   注册
别人写的类已经写好了,没有注解,所有要bean来注册,注入IOC。

set 注入

set注入和getBean 注入,本质上没有区别。
set 注入
private DataSource dataSource;
public void setDataSource(DataSource ds){
	this.dataSource = ds;
}

从 Spring getBean

@Autowired 注解原理是如何实现

@Autowired:
    1.getBean(数据类型)
    2.绑定到某个成员变量
    
@Autowired顾名思义,就是自动装配,其作用是为了消除代码Java代码里面的getter/setter与bean属性中的property。当然,getter看个人需求,如果私有属性需要对外提供的话,应当予以保留。

@Autowired默认按类型匹配的方式,在容器查找匹配的Bean,当有且仅有一个匹配的Bean时,Spring将其注入@Autowired标注的变量中。
@Autowired  
private AccountDao accountDao;
//@Autowired  通过反射的方式把account创建出来 AccountDao accountDao=getBean(AccountDao.calss)

@Override
public List<Account> selectAll() {
	return accountDao.selectAll();
}

在这里插入图片描述

@Autowired 根据bean 类型从spring 上线文中进行查找,注册类型必须唯一,否则报异常。与@Resource 的区别在于,@Resource 允许通过bean 名称或bean 类型两种方式进行查找@Autowired(required=false) 表示,如果spring 上下文中没有找到该类型的bean 时, 才会使用new SoftPMServiceImpl();
<bean id="zoo" class="com.spring.model.Zoo" />
<bean id="tiger" class="com.spring.model.Tiger" />
<bean id="monkey" class="com.spring.model.Monkey" />

在这里插入图片描述

@Qualifier(指定注入Bean的名称)

如果容器中有一个以上匹配的Bean,则可以通过@Qualifier注解限定Bean的名称

作用:在按照类中注入的基础之上再按照名称注入。它在给类成员注入时不能单独使用(可以跟Autowired搭配之用)。但是在给方法参数注入时可以。

        属性:value:用于指定注入bean的id。
@Qualifier 和@AutoWired联合使用,自动装配的策略就变成byName
使用@Autowired 时,如果找到多个同一类型的bean,则会抛异常,此时可以使用 @Qualifier("beanName"),明确指定bean的名称进行注入,此时与 @Resource指定name属性作用相同。
    @Qualifier(value = "限定标识符") // 字段、方法、参数  1)XML配置中的<qualifier>标签指定的名字进行注入
    <qualifier  type="org.springframework.beans.factory.annotation.Qualifier"  value="限定标识符"/>

其中type属性可选,指定类型,默认就是Qualifier注解类,name就是给Bean候选者指定限定标识符,一个Bean定义中只允许指定类型不同的<qualifier>,如果有多个相同type后面指定的将覆盖前面的。
@Autowired    
   //根据<qualifier>标签指定Bean限定标识符    
   public void initDataSource(@Qualifier("mysqlDataSource") DataSource dataSource) {    
       this.dataSource = dataSource;    
   }

使用@Qualifier("mysqlDataSource")来指定候选Bean的限定标识符,我们需要在配置文件中使用<qualifier>标签来指定候选Bean的限定标识符“mysqlDataSource”:
    <bean id="mysqlDataSourceBean" class="org.springframework.jdbc.datasource.DriverManagerDataSource">   
         <qualifier value="mysqlDataSource"/>   
    </bean>2)缺省的根据Bean名字注入 :最基本方式,是在Bean上没有指定<qualifier>标签时一种容错机制,即缺省情况下使用Bean标识符注入,但如果你指定了<qualifier>标签将不会发生容错。 
    @Autowired  
    @Qualifier(value = "mysqlDataSource2") //指定Bean限定标识符   
    //@Qualifier(value = "mysqlDataSourceBean")   
    //是错误的注入,不会发生回退容错,因为你指定了<qualifier>   
    public void initDataSource(DataSource dataSource) {   
        this.dataSource = dataSource;   
    }3)扩展@Qualifier限定描述符注解: 对@Qualifier的扩展来提供细粒度选择候选者; 
如果我们有两个数据源,分别为Mysql和Oracle,因此注入两者相关资源时就牵扯到数据库相关,如在DAO层注入SessionFactory时,当然可以采用前边介绍的方式,但为了简单和直观我们希望采用自定义注解方式。

1.扩展@Qualifier限定描述符注解来分别表示Mysql和Oracle数据源

/** 表示注入Mysql相关 */  
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER})   
@Retention(RetentionPolicy.RUNTIME)   
@Qualifier  
public @interface Mysql {   
}  

@Autowired  
public void initDataSource(@Mysql DataSource mysqlDataSource) {   
    this.mysqlDataSource = mysqlDataSource;   
}   

<bean id="mysqlDataSourceBean" class="org.springframework.jdbc.datasource.DriverManagerDataSource">   
     <qualifier value="mysqlDataSource"/>   
     <qualifier type="cn.javass.spring.chapter12.qualifier.Mysql"/>   
</bean>   
 
 Assert.assertEquals(ctx.getBean("mysqlDataSourceBean"), testBean33.getMysqlDataSoruce());  

2.扩展参数的注解

package cn.javass.spring.chapter12.qualifier;   
public enum DataBase {   
    MYSQL;
}  

@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER})   
@Retention(RetentionPolicy.RUNTIME)   
@Qualifier  
public @interface DataSourceType {   
    String ip();      //指定ip,用于多数据源情况   
    DataBase database();//指定数据库类型   
}  

@Autowired  
    public void initDataSource(   
            @DataSourceType(ip="localhost", database=DataBase.MYSQL)   
            DataSource mysqlDataSource,   
        this.mysqlDataSource = mysqlDataSource;   
    }   

<bean id="mysqlDataSourceBean" class="org.springframework.jdbc.datasource.DriverManagerDataSource">   
    <qualifier value="mysqlDataSource"/>   
    <qualifier type="cn.javass.spring.chapter12.qualifier.Mysql"/>   
    <qualifier type="cn.javass.spring.chapter12.qualifier.DataSourceType">   
        <attribute key="ip" value="localhost"/>   
        <attribute key="database" value="MYSQL"/>   
    </qualifier>   
</bean>

Assert.assertEquals(ctx.getBean("mysqlDataSourceBean"), testBean34.getMysqlDataSource());   

@Resource 注解的工作原理

@Resource注解与@Autowired注解作用非常相似

@Resource等价于 getBean

@Resource:
    1.getBean(id)
    2.绑定到某个成员变量
    
作用:直接按照bean的id注入,它可以独立使用。
属性:name:用于指定bean的id。

要为该属性赋值或注入时需要到这个注解

@Resource(name="xxx"),相当于为该属性注入一个名称为"xxx"的<bean>。
	<bean id="accountDao" class="com.chen.dao.AccountDao"></bean>
    
这是详细一些的用法,说一下@Resource的装配顺序:
(1)、@Resource后面没有任何内容,默认通过name属性去匹配bean,找不到再按type去匹配
(2)、指定了name或者type则根据指定的类型去匹配bean
(3)、指定了name和type则根据指定的name和type去匹配bean,任何一个不匹配都将报错

然后,区分一下@Autowired和@Resource两个注解的区别:
(1)、@Autowired默认按照byType方式进行bean匹配,@Resource默认按照byName方式进行bean匹配
(2)、@Autowired是Spring的注解,@Resource是J2EE的注解,这个看一下导入注解的时候这两个注解的包名就一清二楚了
Spring属于第三方的,J2EE是Java自己的东西,因此,建议使用@Resource注解,以减少代码和Spring之间的耦合。

在这里插入图片描述

< property name=“name” value=“奔驰500” />

在这里插入图片描述

三层架构

在这里插入图片描述

SpringMVC IOC 容器

在这里插入图片描述
在这里插入图片描述

Spring IOC 容器 Service 和 Dao

在这里插入图片描述

注入方式-1 构造方法注入

使用构造函数完成依赖注入的实例
在这里插入图片描述

@Component 注解的原理

<context:component-scan base-package="com.chen.dao,com.chen.service" />
作用:
1.默认单例
2.Component:把该类通过反射Class.forName() 获取类对象,通过类对象 .newInstance 创建实例,保存在 IOC 容器,默认 id 就算类名称(包名,类名)
	通用注解

和它功能相同的还有

  1. Controller: 一般用在表现层 (Spring IOC 容器)
  2. Service: 一般用在业务层 (Spring IOC 容器)
  3. Respository: 一般用在持久层 (Spring IOC 容器)

注意-扫描包的范围

在这里插入图片描述

SpringMVC 扫描配置
<context:component-scan base-package="cn.lusq.controller"></context>

@Repository

@Repository 给Dao层用的
标记数据持久化
创建bean 放到容器里头
    @Repository("accountDao") 等同于 <bean id="accountDao" class="com.chen.dao.IAccountDaoImpl"></bean>

在这里插入图片描述

//@Repository("accountDao") 等同于 <bean id="accountDao" class="com.chen.dao.IAccountDaoImpl"></bean>
@Repository("accountDao") 
public class IAccountDaoImpl implements IAccountDao {
    @Override
    public void saveAccount(Account account) {
        System.out.println("Dao:保存了"+account);
    }
}

@Component

@Component (把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="" class="">)
@Component 是 @Repository 的元注解
@Component 是 @Service 的元注解

@Service

@Service 是给服务层用的
标记业务处理
作用:
@Service注解用于类上,标记当前类是一个service类,加上该注解会将当前类自动注入到spring容器中,不需要再在applicationContext.xml文件定义bean了。

1、 其getBean的默认名称是类名(头字母小写),可以@Service(“xxxx”)这样来指定。
2、其定义的bean默认是单例的,可以使用@Service(“beanName”) @Scope(“prototype”)来改变。
3、可以通过@PostConstruct和@PreDestroy指定初始化方法和销毁方法(方法名任意)。

@Controller

@controller 控制器(注入服务)
用来标记后端控制器

总结:

1.<bean id="" class="" />
2.@component @Service @Respository @Controller
3.解决如何让IOC创建一个单例对象,并且放在IOC容器,等待getBean 或 @Resource @Autowired 来获取它

控制反转

1.注册BookDaoImpl到IOC容器
    1.注解 @Component   (@Respository,@Service,@Controller)
    2.<bean id="" class=""></bean>
2.getBean
	1.byName(id) @Resource
	2.byType @Autowired

SpringIOC 基本思想

1.除了 实体类,工具类以外,其他想办法放到IOC容器里面
	-注解 @Component
	-<bean id="" class=""></bean>
2.getBean
	@Autowired
	@Resource
	@Autowired+@Qualifier == @Resource
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值