Spring IOC容器

六、自动装配

1.自动装配的概念

②手动装配:以value或ref的方式明确指定属性值都是手动装配。

③自动装配:根据指定的装配规则,不需要明确指定,Spring自动将匹配的属性值注入bean中。

2.装配模式

①根据类型自动装配:将类型匹配的bean作为属性注入到另一个bean中。若IOC容器中有多个与目标bean类型一致的bean,Spring将无法判定哪个bean最合适该属性,所以不能执行自动装配

②根据名称自动装配:必须将目标bean的名称和属性名设置的完全相同

③通过构造器自动装配:当bean中存在多个构造器时,此种自动装配方式将会很复杂。不推荐使用。

3.选用建议

相对于使用注解的方式实现的自动装配,在XML文档中进行的自动装配略显笨拙,在项目中更多的使用注解的方式实现。

七、SpEL

1.简介

Spring Expression Language,Spring表达式语言,简称SpEL。支持运行时查询并可以操作对象图。

和JSP页面上的EL表达式、Struts2中用到的OGNL表达式一样,SpEL根据JavaBean风格的getXxx()、setXxx()方法定义的属性访问对象图,完全符合我们熟悉的操作习惯。

 

2.基本语法

SpEL使用#{…}作为定界符,所有在大框号中的字符都将被认为是SpEL表达式。

 

3.使用字面量

●整数:<property name="count" value="#{5}"/>

●小数:<property name="frequency" value="#{89.7}"/>

●科学计数法:<property name="capacity" value="#{1e4}"/>

●String类型的字面量可以使用单引号或者双引号作为字符串的定界符号

<property name=“name” value="#{'Chuck'}"/>

<property name='name' value='#{"Chuck"}'/>

●Boolean:<property name="enabled" value="#{false}"/>

 

4.引用其他bean

<bean id="emp04" class="com.atguigu.parent.bean.Employee">

<property name="empId" value="1003"/>

<property name="empName" value="Kate"/>

<property name="age" value="21"/>

<property name="detp" value="#{dept}"/>

</bean>

 

5.引用其他bean的属性值作为自己某个属性的值

<bean id="emp05" class="com.atguigu.parent.bean.Employee">

<property name="empId" value="1003"/>

<property name="empName" value="Kate"/>

<property name="age" value="21"/>

<property name="deptName" value="#{dept.deptName}"/>

</bean>

 

6.调用非静态方法

<!-- 创建一个对象,在SpEL表达式中调用这个对象的方法 -->

<bean id="salaryGenerator" class="com.atguigu.spel.bean.SalaryGenerator"/>

 

<bean id="employee" class="com.atguigu.spel.bean.Employee">

<!-- 通过对象方法的返回值为属性赋值 -->

<property name="salayOfYear" value="#{salaryGenerator.getSalaryOfYear(5000)}"/>

</bean>

 

7.调用静态方法

<bean id="employee" class="com.atguigu.spel.bean.Employee">

<!-- 在SpEL表达式中调用类的静态方法 -->

<property name="circle" value="#{T(java.lang.Math).PI*20}"/>

</bean>

 

8.运算符

①算术运算符:+、-、*、/、%、^

②字符串连接:+

③比较运算符:<、>、==、<=、>=、lt、gt、eq、le、ge

④逻辑运算符:and, or, not, |

⑤三目运算符:判断条件?判断结果为true时的取值:判断结果为false时的取值

⑥正则表达式:matches

 

八、通过注解配置bean

1.概述

相对于XML方式而言,通过注解的方式配置bean更加简洁和优雅,而且和MVC组件化开发的理念十分契合,是开发中常用的使用方式。

 

2.使用注解标识组件

①普通组件:@Component

标识一个受Spring IOC容器管理的组件

②持久化层组件:@Respository

标识一个受Spring IOC容器管理的持久化层组件

③业务逻辑层组件:@Service

标识一个受Spring IOC容器管理的业务逻辑层组件

④表述层控制器组件:@Controller

标识一个受Spring IOC容器管理的表述层控制器组件

⑤组件命名规则

[1]默认情况:使用组件的简单类名首字母小写后得到的字符串作为bean的id

[2]使用组件注解的value属性指定bean的id

 

注意:事实上Spring并没有能力识别一个组件到底是不是它所标记的类型,即使将@Respository注解用在一个表述层控制器组件上面也不会产生任何错误,所以@Respository、@Service、@Controller这几个注解仅仅是为了让开发人员自己明确当前的组件扮演的角色。

 

3.扫描组件

组件被上述注解标识后还需要通过Spring进行扫描才能够侦测到。

①指定被扫描的package

<context:component-scan base-package="com.atguigu.component"/>

 

②详细说明

[1]base-package属性指定一个需要扫描的基类包,Spring容器将会扫描这个基类包及其子包中的所有类。

[2]当需要扫描多个包时可以使用逗号分隔。

[3]如果仅希望扫描特定的类而非基包下的所有类,可使用resource-pattern属性过滤特定的类,示例:

<context:component-scan 

base-package="com.atguigu.component" 

resource-pattern="autowire/*.class"/>

 

[4]包含与排除

●<context:include-filter>子节点表示要包含的目标类

注意:通常需要与use-default-filters属性配合使用才能够达到“仅包含某些组件”这样的效果。即:通过将use-default-filters属性设置为false,禁用默认过滤器,然后扫描的就只是include-filter中的规则指定的组件了。

●<context:exclude-filter>子节点表示要排除在外的目标类

●component-scan下可以拥有若干个include-filter和exclude-filter子节点

●过滤表达式

类别

示例

说明

annotation

com.atguigu.XxxAnnotation

过滤所有标注了XxxAnnotation的类。这个规则根据目标组件是否标注了指定类型的注解进行过滤。

assignable

com.atguigu.BaseXxx

过滤所有BaseXxx类的子类。这个规则根据目标组件是否是指定类型的子类的方式进行过滤。

aspectj

com.atguigu.*Service+

所有类名是以Service结束的,或这样的类的子类。这个规则根据AspectJ表达式进行过滤。

regex

com\.atguigu\.anno\.*

所有com.atguigu.anno包下的类。这个规则根据正则表达式匹配到的类名进行过滤。

custom

com.atguigu.XxxTypeFilter

使用XxxTypeFilter类通过编码的方式自定义过滤规则。该类必须实现org.springframework.core.type.filter.TypeFilter接口

 

③JAR包

必须在原有JAR包组合的基础上再导入一个:spring-aop-4.0.0.RELEASE.jar

4.组件装配

①需求

Controller组件中往往需要用到Service组件的实例,Service组件中往往需要用到Repository组件的实例。Spring可以通过注解的方式帮我们实现属性的装配。

②实现依据

在指定要扫描的包时,<context:component-scan> 元素会自动注册一个bean的后置处理器:AutowiredAnnotationBeanPostProcessor的实例。该后置处理器可以自动装配标记了@Autowired、@Resource或@Inject注解的属性。

③@Autowired注解

[1]根据类型实现自动装配。

[2]构造器、普通字段(即使是非public)、一切具有参数的方法都可以应用@Autowired注解

[3]默认情况下,所有使用@Autowired注解的属性都需要被设置。当Spring找不到匹配的bean装配属性时,会抛出异常。

[4]若某一属性允许不被设置,可以设置@Autowired注解的required属性为 false

[5]默认情况下,当IOC容器里存在多个类型兼容的bean时,Spring会尝试匹配bean的id值是否与变量名相同,如果相同则进行装配。如果bean的id值不相同,通过类型的自动装配将无法工作。此时可以在@Qualifier注解里提供bean的名称。Spring甚至允许在方法的形参上标注@Qualifiter注解以指定注入bean的名称。

[6]@Autowired注解也可以应用在数组类型的属性上,此时Spring将会把所有匹配的bean进行自动装配。

[7]@Autowired注解也可以应用在集合属性上,此时Spring读取该集合的类型信息,然后自动装配所有与之兼容的bean。

[8]@Autowired注解用在java.util.Map上时,若该Map的键值为String,那么 Spring将自动装配与值类型兼容的bean作为值,并以bean的id值作为键。

④@Resource

@Resource注解要求提供一个bean名称的属性,若该属性为空,则自动采用标注处的变量或方法名作为bean的名称。

⑤@Inject

@Inject和@Autowired注解一样也是按类型注入匹配的bean,但没有reqired属性。

九、泛型依赖注入

1.简介

Spring 4.x中可以为子类注入子类对应的泛型类型的成员变量的引用。

2.实现

[1]组件基类

BaseRepository

public class BaseRepository<T> {

 

public void save() {

System.out.println("Saved by BaseRepository");

}

 

}

 

BaseService

public class BaseService<T> {

 

@Autowired

private BaseRepository<T> repository;

 

public void add() {

repository.save();

}

 

}

 

[2]组件实体类

UserRepository

@Repository

public class UserRepository extends BaseRepository<User>{

 

public void save() {

System.out.println("Saved by UserRepository");

}

 

}

 

UserService

@Service

public class UserService extends BaseService<User>{

 

}

 

[3]模型实体类

User

public class User {

 

}

 

[4]测试

ApplicationContext ioc = new ClassPathXmlApplicationContext("di.xml");

 

UserService us = (UserService) ioc.getBean("userService");

 

us.add();

 

执行结果

Saved by UserRepository

 

十、整合多个配置文件

Spring允许通过<import>将多个配置文件引入到一个文件中,进行配置文件的集成。这样在启动Spring容器时,仅需要指定这个合并好的配置文件就可以。

import元素的resource属性支持Spring的标准的路径资源

 

本教程由尚硅谷教育大数据研究院出品,如需转载请注明来源。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值