目录
一. IOC和DI
IOC-Inversion of Control,译为控制反转
是面向对象编程的一种设计原则,减低代码之间耦合度。
IOC就是把传统程序中需要实现对象的创建、代码的依赖,反转给一个专门的"第三方"即容器来实现,即将创建和查找依赖对象的控制权交给容器,由容器将对象进行组合注入,实现对象与对象的松耦合,便于功能的复用,使程序的体系结构更灵活。
总结:
把创建对象的权利交给框架,主要作用是削减计算机程序的耦合,并不能完全消除。
DI-Dependency Injection,译为依赖注入
实际上是对Ioc的另一种称呼。
所谓依赖注入,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中。
二. Spring容器与Bean
1. spring核心容器
spring的核心容器包括了:Beans、Core、Context、SpEL
① Beans和Core模块提供了整个框架最基础的部分
包括了IOC和DI。
② Context建立在Core和Beans模块提供的基础之上:
Context提供了框架式访问对象的方式
③ Beans、Core、Context构成了Spring的骨架
④ SpEL:提供了一种强大的用于在运行时操作对象的表达式语言
核心容器的两个接口:
1.ApplicationContext:
创建对象采取的策略是 立即加载---------只要读取完配置文件马上创建配置文件中的配置对象。
2.BeanFactory:
创建对象采取的策略是 延迟加载---------也就是说根据ID获取对象,什么时候才是真正创建
2. spring与bean的关系
Spring容器是Spring的核心,一切SpringBean都存储在Spring容器内。
可以说bean是spring核心中的核心。
Bean配置信息定义了Bean的实现及依赖关系,Spring容器根据各种形式的Bean配置信息来创建Bean实例,并调用Bean实例的方法来完成“依赖注入”,可以把Spring容器理解成一个大型工厂,Bean就是该工厂的产品,工厂(Spirng容器)里能生产出来什么样的产品(Bean),完全取决于配置文件中的配置。而这个配置是由开发人员创建和维护的。
3. Bean的作用域
spring的作用域有singleton,prototype, request,session,globle session。
这里只讨论常用的singleton(单例)和prototype(原型)两种作用域
singleton(单例)作用域:
每次请求同id的Bean都将获得相同的实例,spring容器负责跟踪Bean实例状态,负责维护Bean实例的生命周期。
prototype(原型)作用域:
每次请求同id的Bean会获得新的实例,spring容器只负责创建,一旦创建成功就撒手不管,不再管理Bean实例的生命周期,也不会维护Bean实例的状态。
4. 容器中Bean的生命周期
4.1初始化:
Spring提供两种方式在Bean全部属性设置成功后执行特定行为
使用init-method 属性 (代码污染小)
在类中编写一个方法,在属性中指定该方法在依赖关系设置完成后自动执行。
实现InitializingBean接口(耦合较高)
4.2活着
编写afterPropertiesSet()方法的具体实现
4.3死亡
同理,若在Bean销毁之前,执行特定的方法,只需要使用 destroy-method属性或实现DisposableBean接口(实现destroy()方法)
5. Bean标签属性
① id属性:Bean的名称在IOC容器中必须是唯一的。
② class属性:指定Bean对应实现类的全类名,即包名加类名,必须有无参构造。
③ scope属性: 前面提到过的作用域属性,不指定默认为singleton,即单实例模式。
④ name属性:设置<bean>标签的别名,多个别名之间用逗号或空格分开。
⑤ parent属性:子类Bean定义它所引用它的父类Bean。子类Bean定义它所引用它的父类Bean。这时前面的class属性失效。子类Bean会继承父类Bean的所有属性,子类Bean也可以覆盖父类Bean的属性。注意:子类Bean和父类Bean是同一个Java类。
⑥ abstract属性:用来定义Bean是否为抽象Bean。它表示这个Bean将不会被实例化,一般用于父类Bean,因为父类Bean主要是供子类Bean继承使用。
⑦ singleton属性:作用同③,默认为true
⑧ lazy-init属性:用来定义这个Bean是否实现懒初始化。如果为“true”,它将在BeanFactory启动时初始化所有的SingletonBean。反之,如果为“false”,它只在Bean请求时才开始创建SingletonBean。
⑨ autowire属性:它定义了Bean的自动装载方式。“no”:不使用自动装配功能。“byName”:通过Bean的属性名实现自动装配。“byType”:通过Bean的类型实现自动装配。“constructor”:类似于byType,但它是用于构造函数的参数的自动组装。“autodetect”:通过Bean类的反省机制(introspection)决定是使用“constructor”
⑩ dependency-check属性:它用来确保Bean组件通过JavaBean描述的所以依赖关系都得到满足。在与自动装配功能一起使用时,它特别有用。none:不进行依赖检查objects:只做对象间依赖的检查。simple:只做原始类型和String类型依赖的检查。all:对所有类型的依赖进行检查。它包括了前面的objects和simple。
⑪ depends-on属性:这个Bean在初始化时依赖的对象,这个对象会在这个Bean初始化之前创建。
⑫ init-method属性:用来定义Bean的初始化方法,它会在Bean组装之后调用。它必须是一个无参数的方法。
⑬ destroy-method属性:用来定义Bean的销毁方法,它在BeanFactory关闭时调用。同样,它也必须是一个无参数的方法。它只能应用于singletonBean。
⑭ factory-method属性:定义创建该Bean对象的工厂方法。它用于下面的“factory-bean”,表示这个Bean是通过工厂方法创建。此时,“class”属性失效。
⑮ factory-bean属性:定义创建该Bean对象的工厂类。如果使用了“factory-bean”则“class”属性失效。
三. spring中bean配置
bean配置有三种方法:
1、配置形式:
①基于xml文件 (构造方法、Set方法、集合) ②基于注解(共11种基本注解) ③基于java类(学习SpringBoot时用到的)
2、配置方式:
①通过全类名(反射)
②通过工厂方法(静态工厂方法、实例工厂方法)
③FactoryBean
3、依赖注入方式:
①属性(最常用的方式)注入; 使用<property>,使用Set方法时使用这个标签
②构造器注入;使用<constructor-arg>,使用构造方法时使用这个标签
1. 基于xml 全类名 属性注入
<bean id="helloWorld" class="top.arioso.spring.beans.HelloWorld">
<property name="id">
<value>123456</value>
</property>
<property name="age" value="18"></property>
</bean>
property节点:为Bean属性赋值,name为属性名,value对应属性值,属性值要有setter方法
value属性可用子节点value替代
2. 基于xml 全类名 构造器注入
<bean id="person" class="top.arioso.spring.beans.Person">
<constructor-arg type="java.lang.String">
<value>John</value>
</constructor-arg>
<constructor-arg value="America" index="3"><constructor>
<constructor-arg value="123456" type="int"><constructor>
<constructor-arg value="man" typ><constructor>
<property name="id">
<value>123456</value>
</property>
<property name="age" value="18"></property>
</bean>
要求必须有带参构造
根据value值匹配构造器,匹配不到就匹配下一个
可以用index属性指定带参构造器第几个参数
可以用type属性指定构造函数参数类型的匹配
value属性可用子节点value替代
3. spring配置Bean注入
① 配置字面值
可通过value属性或<value>标签属性注入,
若字面值包含特殊字符,使用<![CDATA[]]>包裹
spring将属性的空参数当空String,下面给email属性设置了空的String值("")
<bean id="nullBean" class="top.arioso.spring.NullBean">
<property name="email" value="" />
</bean>
如果要注入null值,可以使用<null />
<bean id="exampleBean" class="top.arioso.spring.NullBean">
<property name="email">
<null />
</property>
</bean>
② Bean之间的引用
<bean id="dog" class="top.arioso.hello.Dog"/>
<bean id="user" class="top.arioso.hello.User">
<property name="name" value="tony"/>
<property name="dog" ref="dog"></property>
</bean>
③ List属性(set同理)
<bean id="user" class="top.arioso.hello.User">
<property name="list">
<list>
<value>北京</value>
<value>上海</value>
<value>广州</value>
<ref bean="dog"/>
</list>
</property>
</bean>
④ map属性
<bean id="user" class="top.arioso.hello.User">
<property name="map">
<map>
<entry key="bj" value="北京"/>
<entry key="sh" value="上海"/>
</map>
</property>
</bean>
⑤ Properties属性
<bean id="user" class="top.arioso.hello.User">
<property name="dbParams">
<props>
<prop key="username">root</prop>
<prop key="password">root</prop>
</props>
</property>
</bean>
⑥ 独立的集合Bean
<util:list id="computerList">
<ref bean="computer"/>
<bean class="top.arioso.spring.collection.ComputerList">
<constructor-arg value="hp"></constructor-arg>
<constructor-arg value="dell"></constructor-arg>
<constructor-arg value="acer"></constructor-arg>
</bean>
</util:list>
<bean id="User" class="top.arioso.spring.User">
<property name="id" value="2018310"></property>
<property name="name" value="Tom"></property>
<property name="computers" value="computerList"></property>
</bean>
⑦ 使用p命名空间
<bean id="computer" class="top.arioso.spring.Computer">
<p:brand="dell" p-cpu="i7-7700" p-price="7900">
</bean>
首先需要导入命名空间
4. 注解配置Bean
4.1:用于创建对象的
@Component
作用:用于把当前类对象存入Spring容器中
属性:value-指定bean的id,当不写是,默认是当前类名,且首字母小写
衍生出以下三个注解:作用和属性和Component一样,作用就是提供明确的三层注解,使我们对三层对象更加清晰!
1.@Controller:用在表现层
2.@Service: 用在业务层
3.@Repository:用在持久层
4.2:用于注入数据的
1.@Autowired:
自动按照类型注入,只要容器中有唯一一个bean对象的类型和要注入的变量类型匹配,就可成功注入
2.@Qualifier:
不可单独使用,依赖Autowired,如果变量相同ID一致 ,给类成员注入不能单独使用,由这个注解指定
3.@Resource:
直接按照bean的id注入,可以单独使用
以上三种只能注入bean其它类型数据,不包括String类型。
4.@Value:
用于注入基本类型和String类型
4.3:用于改变作用范围的
@Scope:
指定bean的作用范围
常用的取值是singleton protptype
4.4:和生命周期有关
@PostConstruct
用于指定初始化方法
@PreDestroy
用于指定销毁方法