Spring中的IOC是什么意思,为什么要用IOC而不是New来创建实例?

大家好,我是IT修真院深圳分院第十三期学员,一枚正直纯洁善良的JAVA程序员。

今天给大家分享一下,修真院官网JAVA任务一,扩展思考中的知识点——Spring中的IOC是什么意思,为什么要用IOC而不是New来创建实例?

一、背景介绍

Spring框架是个轻量级的Java EE框架。所谓轻量级,是指不依赖于容器就能运行的。Struts、Hibernate也是轻量级的。
  轻量级框架是相对于重量级框架而言的,重量级框架必须依赖特定的容器,例如EJB框架就必须运行在Glassfish、JBoss等支持EJB的容器中,而不能运行在Tomcat中。——《Java Web整合开发 王者归来》
  Spring以IoC、AOP为主要思想,其中IoC,Inversion of Control 指控制反转或反向控制。在Spring框架中我们通过配置创建类对象,由Spring在运行阶段实例化、组装对象。AOP,Aspect Oriented Programming,面向切面编程,其思想是在执行某些代码前执行另外的代码,使程序更灵活、扩展性更好,可以随便地添加、删除某些功能。Servlet中的Filter便是一种AOP思想的实现。
  Spring同时也是一个“一站式”框架,即Spring在JavaEE的三层架构[表现层(Web层)、业务逻辑层(Service层)、数据访问层(DAO层)]中,每一层均提供了不同的解决技术。
表现层(Web层):Spring MVC
业务逻辑层(Service层):Spring的IoC
数据访问层(DAO层):Spring的jdbcTemplate

二、 知识剖析

1.IOC是什么?
Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
Spring所倡导的开发方式就是如此,所有的类都会在spring容器中登记,告诉spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。
Bean工厂(BeanFactory接口),提供了基础的依赖注入支持。
应用上下文(ApplicationContext接口),建立在Bean工厂基础之上,提供了系统架构服务。
2.Bean
由IoC容器管理的那些组成你应用程序的对象我们就叫它Bean, Bean就是由Spring容器初始化、装配及管理的对象,除此之外,bean就与应用程序中的其他对象没有什么区别了。
Bean命名约定:Bean的命名遵循XML命名规范,但最好符合Java命名规范,由“字母、数字、下划线组成“,而且应该养成一个良好的命名习惯, 比如采用“驼峰式”,即第一个单词首字母开始,从第二个单词开始首字母大写开始,这样可以增加可读性。
3.Bean的常用属性
1.id——唯一标识,IoC容器中的bean的id标签不能重复,要求符合XML ID 命名规则
2.name——名称标识,相当于别名也不可重复,基本用不到(解决struts1)遗留问题
3.class——全限定类名,指向classpath下类定义所在位置,就是包名加类名package.classname
4.scope——作用范围,可以设置(singleton,prototype,request,session,globalsession),两个常用的
singleton:单实例,默认值;
prototype:单词本意是原型,这里叫做多实例,意思应该就是以它为原型创建多个实例对象。
4.Bean的实例化方式
1.有参无参构造办法
2.静态工厂
3.实例工厂
5.bean的实例化方式
1.有参构造注入
2.set方法
3.P名称属性注入
4.接口的方法(几乎用不到)
6.bean的自动注解方式
最开始Spring只有@Component,不过为了阅读性,以及让注解的用途清晰,衍生出了下面三个:
@Controller web层; @Service 业务层; @Repository 持久层。
@Repository 只能标注在 DAO 类上呢?这是因为该注解的作用不只是将类识别为Bean,同时它还能将所标注的类中抛出的数据访问异常封装为 Spring 的数据访问异常类型。Spring本身提供了一个丰富的并且是与具体的数据访问技术无关的数据访问异常结构,用于封装不同的持久层框架抛出的异常,使得异常独立于底层的框架。
开启注解配置:

三、常见问题

1、BeanFactory和ApplicationContext有什么区别?
2. Spring Bean的生命周期?

四、解决方案

1.BeanFactory 可以理解为含有bean集合的工厂类。BeanFactory 包含了种bean的定义,以便在接收到客户端请求时将对应的bean实例化。

BeanFactory还能在实例化对象的时生成协作类之间的关系。此举将bean自身与bean客户端的配置中解放出来。BeanFactory还包含 了bean生命周期的控制,调用客户端的初始化方法(initialization methods)和销毁方法(destruction methods)。

从表面上看,application context如同bean factory一样具有bean定义、bean关联关系的设置,根据请求分发bean的功能。但applicationcontext在此基础上还提供了其他的功能。
提供了支持国际化的文本消息;
统一的资源文件读取方式;
已在监听器中注册的bean的事件。

2.Spring Bean的生命周期简单易懂。在一个bean实例被初始化时,需要执行一系列的初始化操作以达到可用的状态。同样的,当一个bean不在被调用时需要进行相关的析构操作,并从bean容器中移除。
Spring bean factory 负责管理在spring容器中被创建的bean的生命周期。Bean的生命周期由两组回调(call back)方法组成。

初始化之后调用的回调方法。
销毁之前调用的回调方法。

五、 编码实战

实例类

package com_twg.POJO;

import org.springframework.stereotype.Component;

@Component(value="user")
public class User {
    public void add(){
        System.out.println("执行User对象的add方法!");
    }
    @Override
    public String toString(){
        return "创建出一个User对象!";
    }
}

静态工厂类

package com_twg.test;
import com_twg.POJO.User;

public class UserFactory {
    public static User createInstance(){
        return new User();
    }
}

实例工厂类

package com_twg.test;

import com_twg.POJO.User;

public class UserFactory2 {
    public User createInstance2(){
        return new User();
    }
}

在XML文件中为User类配置bean的三种方式:

<!--为类class进行bean的配置:
          1.使用类的无参构造函数-->
    <bean id="user" class="com_twg.POJO.User"/>
    <!--  2.使用静态工厂,通过工厂类的某个静态方法创建
    等同于user1 = com_twg.test.User.Factory.createInstance()-->
    <bean id="user1" class="com_twg.test.UserFactory" factory-method="createInstance"/>
<!--  3.使用实例工厂,通过工厂类的某个实例方法创建
    等同于userFactory = new com_twg.test.UserFactory2()-->
    <bean id="userFactory2" class="com_twg.test.UserFactory2"/>
    <!--等同于user2= usrFactory.createInstance();-->
    <bean id="user2" factory-bean="userFactory2" factory-method="createInstance2"/> 

可以看到静态工厂类与实例工厂类的方法是不是static属性的方法。

属性注入
  属性注入指创建对象时,向类对象的属性设置属性值。
  在Spring框架中支持set方法注入和有参构造函数注入,即创建对象后通过set方法设置属性或采用有参构造函数创建对象并初始化属性。
实体类:

package com_twg.POJO;

public class Student {
    private String name;
    public Student(String name) {
        this.name = name;
    }
/*    public void setName(String name) {
        this.name = name;
    }*/
    @Override
    public String toString(){
        return "创建对象Student{"+"name='"+name+'\''+'}';
    }

} 

下面是XML文件中两种属性注入配置方式,在实例类中注释掉的set方法对应的就是第二种set函数属性注入。

    <!--1.配置有参构造函数提供属性注入-->
    <bean id="student" class="com_twg.POJO.Student">
    <constructor-arg name="name" value="DreamBoy"/>
</bean>
    <!--2.配置set函数提供属性注入-->
<!--    <bean id="student1" class="com_twg.POJO.Student">
        <property name="name" value="Harry"/>
    </bean>-->

六、 更多讨论

七、 参考文献

https://blog.csdn.net/qq_22654611/article/details/52606960
https://blog.csdn.net/qq_15096707/article/details/72819930

八、 更多讨论

1.@Autowired和@Resource的区别?
@Autowired,属于Spring的注解,来自于org.springframework.beans.factory.annotation.Autowired
@Resource,不属于Spring的注解,JDK1.6支持的注解,来自于 javax.annotation.Resource
共同点:装配bean. 写在字段上,或写在setter方法
不同点:
@Autowired 默认按类型装配 依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,@Autowired(required=false) ,也可以使用名称装配,配合@Qualifier注解;
@Resource 默认按名称进行装配,通过name属性进行指定。
2、FileSystemResource和ClassPathResource有何区别?
在FileSystemResource 中需要给出spring-config.xml文件在你项目中的相对路径或者绝对路径。在ClassPathResource中spring会在ClassPath中自动搜寻配置文件,所以要把ClassPathResource 文件放在ClassPath下。
如果将spring-config.xml保存在了src文件夹下的话,只需给出配置文件的名称即可,因为src文件夹是默认。
简而言之,ClassPathResource在环境变量中读取配置文件,FileSystemResource在配置文件中读取配置文件。
3.不同方式的自动装配?
有五种自动装配的方式,可以用来指导Spring容器用自动装配方式来进行依赖注入。
no:默认的方式是不进行自动装配,通过显式设置ref 属性来进行装配。
byName:通过参数名 自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byname,之后容器试图匹配、装配和该bean的属性具有相同名字的bean。
byType::通过参数类型自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byType,之后容器试图匹配、装配和该bean的属性具有相同类型的bean。如果有多个bean符合条件,则抛出错误。
constructor:这个方式类似于byType, 但是要提供给构造器参数,如果没有确定的带参数的构造器参数类型,将会抛出异常。
autodetect:首先尝试使用constructor来自动装配,如果无法工作,则使用byType方式。

———–技能树.IT修真院
“我们相信人人都可以成为一个工程师,现在开始,找个师兄,带你入门,掌控自己学习的节奏,学习的路上不再迷茫”。

这里是技能树.IT修真院,成千上万的师兄在这里找到了自己的学习路线,学习透明化,成长可见化,师兄1对1免费指导。

快来与我一起学习吧:http://www.jnshu.com/login/1/28802745
腾讯视频:https://v.qq.com/x/page/n0782f5bqg7.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值