手记

【金秋打卡】第9天 使用注解方式实现Spring Ioc

课程信息

  • 学习课程:Java工程师2022版
  • 章节名称:Spring Ioc容器与Bean管理-使用注解方式实现Spring Ioc
  • 讲师:悟空

课程内容

通过XML、注解或者Java Config配置IoC容器本质是一样的
基于注解配置IoC容器

基于注解的优势:

摆脱繁琐的XML形式的bean与依赖注入配置

基于“声明式”的原则,更适合轻量级的现代企业应用

让代码可读性变得更好,研发人员拥有更好的开发体验

三类注解:

组件类型注解——声明当前类的功能与职责

自动装配注解——根据属性特征自动注入对象

元数据注解——更细化的辅助IoC容器管理对象的注解

四种组件类型注解(在将对象实例化之后还自动注入强化了这个类):

@Component:组件注解,通用注解,被该注解描述的类将被IoC容器管理并实例化

@Controller:语义注解,说明当前类是MVC应用中的控制器类

@Service:语义注解,说明当前类是Service业务服务类

@Repository:语义注解,说明当前类用于业务持久层,通常描述对应Dao类

<context:component-scan base-package=“com.imooc”>
<context:exclude-filter type=“regex” expression=“com.imooc.exl.*”/>
</context:component-scan>

基于注解初始化ioc容器
1.创建基于Spring基于注解的Schema和基于XML文件的不太一样(01:18)处找到具体复制位置

<context:component-scan base-package=“com.imooc”/>

组件类型注解默认beanId为类名首字母小写,也可以在注解后加括号重新命名beanId,一般都使用默认值!而且他们都是单例的,只有单例的会在IoC初始化的时候进行创建

//组件类型注解默认beanId为类名首字母小写userDao
@Repository(“uDao”)
public class UserDao{}

两类自动装配注解

按类型装配 @Autowired 按容器内对象类型动态注入属性,由Spring机构提供

@Inject 基于JSR-330标准,其他同@Autowired,但不支持required属性

按名称装配 @Named 与Inject配合使用,JSR-330规范,按属性名自动装配属性

@Resource 基于JSR-250规范,优先按名称,再按类型智能匹配

为了让IoC容器在运行过程中自动为某个属性注入数据

如果装配注解放在set方法上,则自动按类型/名称对set方法参数进行注入,

但是一般不会设置set方法

因为Spring Ioc容器会自动通过反射技术将属性private修饰符自动改为public,直接进行赋值,然后再改回private

它是在运行时动态完成的,不依赖于set方法

所以用注解开发做依赖注入一般不写set方法

/* 如果装配注解放在属性上, 
* Spring IoC容器会自动通过反射技术将属性private修饰符自动改为public, 
* 也就意味着从外侧可以直接对属性赋值,就直接进行赋值 
* 不执行set方法*/ 
@Autowired private IUserDao udao ; 
/* 如果装配注解放在set方法上,则自动按类型
*名称对set方法参数进行注入   
*ioc容器会自动将容器中类型为UserDao的对象注入到set方法参数中  
*执行set方法中的代码,完成属性的赋值 
*/
@Autowired 
public void setUdao(UserDao udao) {     
	System.out.println("setUdao:" + udao);     
	this.udao = udao; 
}

@Autowired默认是根据类型进行自动装配的,但是当存在多个满足条件的 Bean 时,则会根据名称进行注入。

代码中声明为:private IUserDao userDao,项目中存在两个该类型的Bean,则会继续按照名称进行注入,会直接将UserDao对象注入,故程序可以正常运行。

课程中声明为private IUserDao uDao时,项目中存在两个IUserDao类型的Bean,且不存在名为uDao的bean故会注入失败,出现报错提示“No qualifying bean of type ‘com.imooc.spring.ioc.dao.IUserDao’ available:expected single matching bean but found 2: userDao,userOracleDao

@Autowired默认按照类型byType自动装配,@Resource默认按照名称byName自动装配。

1、@Resource设置name属性,则按name在IoC容器中将Bean注入

2、@Resource未设置name属性:

以属性名作为bean name在IoC容器中匹配Bean,如有匹配则注入

按属性名未匹配,则按类型进行匹配,同@Autowired,需加入@Primary解决类型冲突

使用建议:在使用@Resource对象时推荐设置name或保证属性名与bean名称一致

@Resource

@Resource注解输入J2EE,有两个属性:name和type,而Spring将@Resouce注解的name属性解析为bean的名称,type属性则被解析为bean的类型。@Resource默认按照名称进行装配,名称可以通过name属性进行指定.

@Autowired

@Autowired注解属于Spring,默认按照类型装配,默认情况下要求依赖对象必须存在

@Resource与@Autowired都可以用来装配bean,都可以写在字段或setter方法上。

@Resource默认按照名称进行装配,如果乜有指定name属性,注解写在字段上时,默认是取字段名作为名称进行查找。如果注解写在setter方法上则是默认取属性的名称进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的时,如果name属性一旦指定,就只会按照名称进行装配。

@Resource的装配顺序如下:

1)如果同时指定name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。

2)如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。

3)如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常

4)如果即没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。

@Autowired允许null值,需要将equired属性设置为false.如:@Autowired(required=false)

@Autowired想用名称装配,需要结合@Qualifier注解进行使用。在@Autowire配合@Qualifier使用时,会按照@Qualifier注解添加的名称进行注入。如:@Autowired@Qualifier(“test”)就是按照test名称进行装配。从而解决@Service重名问题

元数据注解

@Primary 按类型装配时出现多个相同类型对象,拥有此注解对象优先被注入

@PostConstruct 描述方法,相当于XML中init-method配置的注解版本

@PreDestroy 描述方法,相当于XML中destroy-method配置的注解版本

@Scope 设置对象的scope属性

@Value 为属性注入静态数据

@Scope(“singleton”);@Scope(“prototype”);用来设置对象是单例模式还是多例模式,和xml中的bean scope完全相同 单例模式在ioc容器初始化之前初始化对象,以后通过getbean获取的对象也都是这一个对象;多例模式在ioc容器初始化后采用getbean的形式调用后才进行对象初始化,且每次的对象都不同

@PostConstruct //与XML中的init-method作用完全相同,每次对象创建时执行完构造方法都要同步执行此方法

在xml中配置加载配置文件:

<!-- 通知SpringIoc容器初始化加载属性文件 -->
<context:property-placeholder location="classpath:config.properties"/>

@Value(${metaData})

@Value("${配置文件里的属性名}")(放在成员属性上,用来定义配置文件(properties/yml文件)中的属性,然后通过调用成员属性来获取配置文件中的属性值(静态数据);(@Value(“配置文件里的属性名”)然后通过调用成员属性来获取配置文件里的属性名))

学习收获

学习了使用注解实现Spring Ioc,常用的组件注解,自动装配注解,元数据注解,组件注解的区别和使用方式,自动装配注解放在属性上和set方法上的区别,以及自动装配注解@Autowired和@Resource的区别,常用的元数据注解用途和使用

打卡截图

0人推荐
随时随地看视频
慕课网APP