发表于: 2018-03-28 22:33:01
1 543
今日完成:小课堂的讲解
今天给大家分享一下,修真院官网JAVA任务一,深度思考中的知识点——Spring中的IOC是什么意思,为什么要用IOC而不是New来创建实例?
1.背景介绍
spring是一种多层的J2EE应用程序框架,是以Rod Johson编写的《Expert one to one J2EE design and development》一书的代码为基础发展而来的。它是为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。spring的两个核心思想就是IOC和AOP。
为了方便解耦,简化开发,spring提供了一种新的设计思想来管理业务对象及其依赖关系,即控制反转IOC。在传统的程序设计中,调用者直接使用new关键字创建对象,是程序主动去创建依赖对象,调用者和被调用者之间的耦合度很高,不利于程序的复用和维护。而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建,这样本来是由程序来创建对象,转变成由IOC容器来创建,总之就是依赖对象的获取被反转了。
至于依赖注入(DI)则是一种实现IOC的技术手段。
2.知识剖析
(1)spring容器
spring容器是 Spring 框架的核心。容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁。 Spring 提供了以下两种不同类型的容器;
BeanFactory 容器:它是最简单的容器,给 DI 提供了基本的支持。在 Spring 中,有大量对 BeanFactory 接口的实现。其中,最常被使用的是 XmlBeanFactory 类。
ApplicationContext 容器:该容器包括 BeanFactory 容器的所有功能,并且该添加了更多的企业特定的功能,例如从一个属性文件中解析文本信息的能力,发布应用程序事件给事件监听器的能力。所以通常建议使用ApplicationContext。
最常被使用的 ApplicationContext 接口实现:
• FileSystemXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你需要提供给构造器 XML 文件的完整路径
• ClassPathXmlApplicationContext:该容器从 XML 文件中加载已被定义的 bean。在这里,你不需要提供 XML 文件的完整路径,只需正确配置 CLASSPATH 环境变量即可,因为,容器会从 CLASSPATH 中搜索 bean 配置文件。
• WebXmlApplicationContext:该容器会在一个 web 应用程序的范围内加载在 XML 文件中已被定义的 bean。
(2)bean的定义
bean 是一个被实例化,组装,并通过 Spring IoC 容器所管理的对象。
bean的几种属性:
class,是必须的,用来指定创建bean的类。
name/id:用来指定唯一bean的标识符。
scope:指定bean的作用域为单例或多例等等,默认为单例。
constructor-arg、properties、autowire:注入依赖关系。
lazy-init:延迟初始化bean告诉IoC容器在它第一次被请求时,而不是在启动时去创建一个bean实例。
initialization和destruction 方法:在bean的所有必需的属性被容器设置之后,调用的回调方法;当包含该bean的容器被销毁时,调用的回调方法。
(3)bean实例化的三种方式
1)无参构造函数
public class Nonparam {
private final Loggerlogger = LoggerFactory.getLogger(Container.class);
private Stringname;
public Nonparam() {
logger.info("这是一个无参构造函数");
this.name=name;
}
}
配置文件中
<bean id="nonparam" class="com.instantiation.constructor.Nonparam"/>
2)静态工厂
有一个Bean类和一个BeanFactory类,其中BeanFactory类中有一个静态方法,返回一个Bean的对象。
public class BeanFactory {
public static Bean getBean() {
return new Bean();
}
}
配置文件
<bean id="bean" class="com.instantiation.staticFactory.factory.BeanFactory" factory-method="getBean"/>
可以看到配置文件中多出了一个factory-method 属性,其值为静态工厂中的静态方法。
3)实例工厂
跟静态工厂类似,只不过BeanFactory中的不再是静态方法,改为实例方法。如下:
public Bean2getBean2() {
return new Bean2();
}
配置文件
<bean id="bean2factory" class="......"/>
<bean id="bean2" factory-bean="bean2factory" factory-method="getBean2"/>
(4)bean的作用域
singleton:该作用域将 bean 的定义的限制在每一个Spring IoC容器中的一个单一实例(默认)。
prototype:限制在任意数量的对象实例。
request、session、global-session:分别为HTTP请求、会话、全局会话。
(5)bean的生命周期
6)依赖注入
有以下几种方式:
(1)设值函数(setter)注入。分为普通属性和域属性
(2)构造方法注入:需要调用带有一组参数的类构造函数。构造器注入有俩种形式 ,一个是根据参数类型 ,一个是根据参数位置的下标
(3)接口注入(不推荐)
(4)注解注入:
常用注解:
a、自动注入:@Resources,@Autowired (spring还有一种基于XML文件的自动装配)
b、Bean定义:@Component、@Repository、@Service 和 @Constroller
3.常见问题
@Autowired和@Resources之间的区别?
4.解决方案
@Autowired默认按类型装配(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false
@Resource 默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名,按照名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
5.编码实战
6.扩展思考
(1)构造方法注入 和set方法注入有什么区别?
使用构造函数依赖注入时,Spring保证所有一个对象所有依赖的对象先实例化后,才实例化这个对象。(没有他们就没有我原则)
使用set方法依赖注入时,Spring首先实例化对象,然后才实例化所有依赖的对象。
虽然在理论上“构造函数注入”和“set方法注入”代表2种不同的依赖强度,但是spring并不会把无效的合作者传递给一个 bean。如果合作者无效或不存在spring会抛出异常,这样spring保证一个对象的合作者都是可用的。所以在spring中,“构造函数注入”和 “set方法注入”唯一的区别在于2种方式创建合作者的顺序不同。
(2)懒加载会不会影响性能
不用懒加载 ,启动程序会慢一点觉得启动卡顿。
用懒加载的话 ,会在使用程序的时候有延迟。
(3)springIOC实现的底层技术
1)xml配置文件
2)dom4j解析xml
3)工厂设计模式
4)反射
7.参考文献
链接:https://www.zhihu.com/question/38597960/answer/77600561
作者:MOBIN-F
链接:https://www.w3cschool.cn/
作者:w3cschool
链接:https://www.cnblogs.com/dannyyao/p/6644225.html
作者:寻坑者
链接:http://blog.sina.com.cn/s/blog_ad071a810101g9wx.html
作者:francis_alice
明天计划的事情:
继续任务二的,ssm框架实现曾删改查
遇到的问题:
小课堂的讲解过程中,发现自己表达不流畅,思维不清晰,经常讲着讲着就接不上下文了。表达与交流需要加强。
收获:
整理了springIOC的知识。
进度:任务二步骤二
任务开始时间:3.23
预计demo时间:3.28
是否延期:否
禅道地址:http://task.ptteng.com/zentao/project-task-562.html
评论