《Spring》实战——2.IOC/DI&装配

Day_01

Bean的定义与装配;(XML、Config.java、自动装配 3种方式)

1. 自动装配(注解)-推荐

Spring从两个角度来实现自动化装配:

(1)组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean。
(2)自动装配(autowiring):Spring自动满足bean之间的依赖。

定义bean?

(1)先定义组件(bean)类的接口(为了解耦);
(2)然后在实现类的类声明上面加一句注解@Component,则这个实现类会被Spring给识别为组件(bean)便于后序的扫描(实际上@Component @Service @Controller @repository都可被识别扫描);也可以指定bean的名字;(也就是说定义为bean的标记加载了bean所在的类的定义上面)在@Component的类里面,可以@value给bean的成员指定初始值;

自动扫描?

(1)Config.java的类声明上面分别加@configuration(表明是个配置类)和@componentScan指定扫描的包路径(默认为当前config.java在的包);

或指定为包中所包含的类或接口:

(2)测试bean的装载;

在test类里面定义一个bean类对象,加上@Autowired注解;然后在test类引入配置的config.java类;然后测试这个bean有没有生成;

装配bean

——把其他bean装入当前bean,像”把多个bean组装起来”?

实现方式:eg:

注意:实际上,@Autowired可以加在当前bean的类的”任意的需要传入其他bean的方法”;

eg:setter或其他需要传参的方法;

当这个作为方法参数传入的bean不存在时,会报错;存在多个匹配的bean的时候,也会报错;解决方法?

(1)当可能不存在匹配的bean;

将required属性设置为false时,Spring会尝试执行自动装配,但是如果没有匹配的bean的话,Spring将会让这个bean处于未装配的状态。但是,把required属性设置为false时,你需要谨慎对待。如果在你的代码中没有进行null检查的话,这个处于未装配状态的属性有可能会出现NullPointerException。

(2)当存在多个bean匹配(使用的是bean类所在的接口,或者确实存在多个同类的bean);

有两种方法:

  1. 使用@Primary提示首选的bean;

  2. 或指定bean的名字;

为@Qualifier注解所设置的参数就是想要注入的bean的ID。所有使用@Component注解声明的类都会创建为bean,并且bean的ID为首字母变为小写的类名;

测试:

则会导入ID为”cold”的bean;

2. Java方式

这种方式应用于,当采用第三方的库的组件,不能@component来自定义bean

上面这种方式为”自动扫描配置”,以下两种为”显示地手动配置”:Java和XML

因为不自动扫描,所以取消了@componentScan,因此自定义的bean的类@component和@autowired就没用了;

直接在@configuration的config.java里面,手动显示的声明bean(@Bean);

注入其他的bean?(装配bean)

1. 可以传@bean的方法;

看似是调用了sgtPeppers()方法,其实这里只是把这个方法看作是一个已生成的bean,即多次调用这个方法,返回的结果是同一个bean;

2. 也可以不显示的申明传入了一个bean参数;(实际上是在参数前省略了@Aotuwired)

在这里甚至没有要求CompactDisc必须要在JavaConfig中声明,实际上它可以通过组件扫描功能自动发现或者通过XML来进行配置;(当出现多个bean匹配,也可以用类似@primary或@qualifier的方式);

3. XML方式

这种方式最基础;与上一种方式相比,(2)中的@configuration的Config.java对应一个beans.xml文件;为简化xml标签,使用了c-、p-命名空间简写,还有针对集合类的简写;

(1)声明+赋值;eg:

eg:装配(采用构造器-注入其他bean)

(2)c-命名空间;

或者:

对于构造器的常量参数:

(3)集合类;

(4)使用setter注入其他bean,先在bean所在的类定义好setter方法;

(5)p-命名空间;

总结来说,加载bean的3种方式:

  1. 自动扫描,自定义类@component;然后在config.java + @configuration + @componentScan; 最后在需要用bean的类里面(可以是一个test类,也可以是另一个bean所在的类)使用@autowired来注入/装配”被扫描出来的且被匹配的bean”;
  2. 与第1种类似,只是config.java里面没有@componentScan,因此就没有了自动扫描;需要显示的在config里面手动@bean+带有返回bean的方法来声明bean;注意,带有@Bean注解的方法可以采用任何必要的Java功能来产生bean实例,构造器和Setter方法只是@Bean方法的两个简单样例;
  3. 与第二种方式一样,@configuration+config.java文件换成了beans.xml文件,@Bean换成了<beans>.<bean id=.. class=..>...;使用构造器/setter方法初始化来注入其他bean(装配bean),分别对应c-/p-命名空间;

Bean的作用域?

Spring定义了多种作用域,可以基于这些作用域创建bean,包括:
(1)单例(Singleton):在整个应用中,只创建bean的一个实例。(默认)
(2)原型(Prototype):每次注入或者通过Spring应用上下文获取的时候,都会创建一个新的bean实例。
(3)会话(Session):在Web应用中,为每个会话创建一个bean实例。
(4)请求(Rquest):在Web应用中,为每个请求创建一个bean实例。

控制作用域?

使用会话和请求作用域?

在Web应用中,例如,在典型的电子商务应用中,可能会有一个bean代表用户的购物车。如果购物车是单例的话,那么将会导致所有的用户都会向同一个购物车中添加商品。另一方面,如果购物车是原型作用域的,那么在应用中某一个地方往购物车中添加商品,在应用的另外一个地方可能就不可用了,因为在这里注入的是另外一个原型作用域的购物车。

就购物车bean来说,会话作用域是最为合适的,因为它与给定的用户关联性最大。要指定会话作用域,我们可以使用@Scope注解,它的使用方式与指定原型作用域是相同的;

运行时注入?懒加载?条件化注入bean?

(1)运行时注入,在设置bean的属性的时候,可以依赖外部配置.properties文件;

(2)懒加载,对于单例bean,默认IOC容器启动的时候就会加载;可以让其懒加载,即第一次获取(从context容器getBean时)这个bean的时候才加载;直接在@Bean上面加@Lazy即可;

(3)条件加载(Spring 4.0)

直接在@Bean上面加@Condition即可;eg:

这个类要实现Condition接口的boolean match(context, type)方法;实现合适才满足条件;这个context可以获取很多信息:BeanFactory工厂、ClassLoader类加载器、Environment系统环境、bean的注册类...通过这些信息来获取条件;

*Bean的生命周期?定义初始化和销毁方法?

在bean所在的类声明初始化/销毁方法,在@Bean里面调用;对于ProtoType,容器则不会调用@Bean里面的销毁方法;

关于@Autowired方法?(装配bean)

@Autowired可以标注到”构造器、方法、属性、方法参数”上面;

1. 在当前的@component的bean类中,标注在setter方法上面;

2. 有参构造器(当只有一个有参构造器时,构造器上/构造器参数的@Autowired可以省写)

或者

写在config类的@Bean方法上

Profile根据环境”激活”bean?

比如,注册了多个@Bean,根据Profile加载不同的bean;

怎么激活环境?

固定写法:

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值