Spring--02--IOC

Spring IOC 控制反转

什么是控制反转

IOC(Inverse Of Control)控制反转,即,把创建对象的权利交给框架。
也就是指将对象的创建、对象的存储、对象的管理交给了spring容器。
(spring容器是spring中的一个核心模块,用于管理对象,底层可以理解为是一个map集合)

在这里插入图片描述
在这里插入图片描述

具体实现

在此之前,当需要对象时,通常是利用new关键字创建一个对象:
在这里插入图片描述
但由于new对象,会提高类和类之间的依赖关系,即代码之间的耦合性。
而现在我们可以将对象的创建交给框架来做:
在这里插入图片描述
只需要将类提前配置在配置文件中,就可以将对象的创建交给框架来做。当需要对象时,不需要自己创建,而是通过框架直接获取即可,省去了new对象的过程,自然就降低类和类之间的依赖关系,也就是耦合性。

Spring 容器高层视图

Spring 启动时读取应用程序提供的Bean 配置信息,并在Spring 容器中生成一份相应的Bean 配
置注册表,然后根据这张注册表实例化Bean,装配好Bean 之间的依赖关系,为上层应用提供准
备就绪的运行环境。其中Bean 缓存池为HashMap 实现
**Map<String,BeanDefiniton>**对象的定义信息
Map<String,object> 管理对象

在这里插入图片描述
在这里插入图片描述

IOC入门案例

下面将使用spring的IOC解决程序间的耦合

1.创建spring配置文件

创建spring核心配置文件—applicationContext.xml
1、在工程的src/main/resources源码目录下,创建applicationContext.xml文件:
在这里插入图片描述
2、在applicationContext.xml中添加文件头信息:
在这里插入图片描述
3、将EmpService接口的实现类的实例
以及EmpDao接口的实现类的实例交给Spring容器创建,在核心配置文件中添加如下配置:
在这里插入图片描述

2.创建测试类进行解耦

创建测试类—TestSpring,通过spring的IOC解决程序中的耦合问题

1、创建测试类
在这里插入图片描述
2、测试步骤及代码如下:
在这里插入图片描述

3、运行结果

在这里插入图片描述

4、入门案例总结:

这就是spring框架的IOC——控制反转。之前我们自己new对象,例如:

在这里插入图片描述
而现在,变成由一个初始化的xml配置文件来创建,也就是由spring容器来创建。
在这里插入图片描述
当程序运行,spring开始工作后,会加载整个xml核心配置文件,读取到,获取到class属性中类的全路径,利用反射创建该类的对象。

Spring框架管理Bean对象的优势

Spring 是一个资源整合框架(Framework),通过spring可将很多资源(自己写的对象或第三方提供的对象,例如连接池等)整合在一起,然后进行科学应用,以便更好的对外提供服务。
在这里插入图片描述
懒加载策略 @Lazy(true) 默认为true
作用域 @Scope(“singleton”) 默认单例
生命周期方法 lifecycle method @PostConstruct @PreDestroy

Spring框架可以为由它管理的对象(Bean)提供懒加载策略(对象暂时用不到,则无需加载和实例化),作用域(例如singleton-频繁用时可以考虑内存中只有一份,prototype-使用次数少时可以用时创建,不用时销毁),生命周期方法(更好实现对象的初始化和资源销毁),以实现对象对系统资源的有效使用。同时Spring框架还可以基于用户设计管理对象与对象的依赖关系,以降低对象与对象之间的直接耦合,提高程序的可维护性和可扩展性。

懒加载(Lazy)

在Spring框架中,默认会在启动时会创建所有的Bean对象,但有些bean对象假如长时间不用,启动时就创建对象,会占用其内存资源,从而造成一定的资源浪费,此时我们可以基于懒加载策略延迟对象的创建,在设计类时,在类上添加@Lazy注解,

@Lazy(true)//此注解用于告诉spring框架,它描述的类的实例,假如暂时用不到,就不要先创建

spring中 @Lazy注解中有一个value属性,其默认值为true表示延迟加载

Spring Bean 作用域(Scope)

Spring框架创建对象以后,可以给对象一个作用域,目的是让对象在一定范围内可以进行重用,默认是单例模式singleton

Spring 3 中为Bean 定义了5 中作用域,分别为singleton(单例)、prototype(原型)、
request、session 和global session,5 种作用域说明如下:

singleton 单例模式(多线程不安全)

  1. singleton:单例模式,Spring IoC 容器中只会存在一个共享的Bean 实例,无论有多少个
    Bean 引用它,始终指向同一对象。该模式在多线程下是不安全的。Singleton 作用域是
    Spring 中的缺省作用域,也可以显示的将Bean 定义为singleton 模式,配置为:

prototype:多例模式(原型模式)每次使用时被创建

  1. prototype:原型模式,每次通过Spring 容器获取prototype 定义的bean 时,容器都将创建
    一个新的Bean 实例,每个Bean 实例都有自己的属性和状态,而singleton 全局只有一个对象。根据经验,对有状态的bean使用prototype作用域,而对无状态的bean使用singleton作用域。

Request:一次request一次实例

  1. request:在一次Http 请求中,容器会返回该Bean 的同一实例。而对不同的Http 请求则会
    产生新的Bean,而且该bean 仅在当前Http Request 内有效,当前Http 请求结束,该bean
    实例也将会被销毁。

session

  1. session:在一次Http Session 中,容器会返回该Bean 的同一实例。而对不同的Session 请求则会创建新的实例,该bean 实例仅在当前Session 内有效。同Http 请求相同,每一次session 请求创建新的实例,而不同的实例之间不共享属性,且实例仅在自己的session 请求内有效,请求结束,则实例将被销毁。

global Session

  1. global Session:在一个全局的Http Session 中,容器会返回该Bean 的同一个实例,仅在
    使用portlet context 时有效。

生命周期方法

程序中每个对象都有生命周期,但不是每个对象类型定义时,都要定义生命周期方法,当一个Bean对象创建以后假如还需执行额外初始化,销毁之前也需要额外的其它资源的释放,Spring框架可以为类定义其生命周期方法。

在这里插入图片描述
bean 标签有两个重要的属性(init-method 和destroy-method)。用它们你可以自己定制
初始化和注销方法。它们也有相应的注解(@PostConstruct 和@PreDestroy)。

在这里插入图片描述

  • @PostConstruct 注解描述的方法会在对象构建以后执行,用于执行一些初始化操作
  • @PreDestroy 注解描述的方法会在单例对象销毁之前执行,spring容器在销毁之前会先将容器(Bean池)中的对象进行移除,在移除对象时,假如对象中定义了生命周期销毁方法,此时还会调用对象的生命周期销毁方法(在这样的方法中可以做一些资源释放操作)。

另:@Scope(“prototype”)创造出来的bean对象不会存在bean池中,所以得手动销毁

一般池对象都会设置一些生命周期方法,例如连接池。

生命周期说明

  1. 对象创建
  2. 初始化数据
  3. 调用方法,完成功能
  4. 对象销毁
    核心: 生命周期的方法都是自动调用!!!
package com.jt.demo6;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * 第三天课程
 */
public class User {

    //1.对象的创建
    public User(){
        System.out.println("用户对象创建成功!!!");
    }

    //2.进行初始化操作
    @PostConstruct
    public void init(){
        System.out.println("为属性赋值!!!");
    }

    //3.进行业务调用  业务方法 用户手动调用!!!
    public void hello(){
        System.out.println("我爱学java");
    }

    //4.销毁方法
    @PreDestroy
    public void destroy(){
        System.out.println("调用销毁方法,释放资源!!!");
    }
}


@PostConstruct 标识初始化方法
@PreDestroy 标识销毁方法.

什么是bean?

在Spring框架中由Spring创建和管理的对象的对象称之为Bean对象。
我们在java中,会把满足一定规范的java对象叫做bean对象。规范如下:
(1)必须是public的类
(2)必须具备无参数构造方法
(3)有公开的get set方法
(4)必须是可序列化(在序列化方式改进之后,这个规范不是必须的)

Serializable

:可序列化接口,是一个标识接口。
序列化的概念:把java对象拆分成一个一个的字节单元,便于存储到磁盘或者用于网络传输。
反序列化:就是把一个一个的字节单元读取回来,组成一个java对象。

在早期,Java要想实现序列化,只能通过java原生的序列化方式,也就是通过实现序列化接口来实现序列化。但是后来随着java的发展,衍生很多的第三方序列化jar包。

他们的序列化性能比原生的更好,而且不需要实现序列化也可以序列化。

Spring DI依赖注入

DI(Dependency Injection)依赖注入 。

依赖注入,即组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。
简单来说,所谓的依赖注入其实就是,在创建对象的同时或之后,如何给对象的属性赋值。

spring有4种依赖注入方式:

Set方法注入
构造器注入
静态工厂的方法注入
实例工厂的方法注入

按照实现方式分为两类:

注解(如@Autowired)
配置文件(如xml)

1、Set方法注入

在这里插入图片描述

2、构造方法注入

构造方法注入是指带有参数的构造函数注入

注解方式

在这里插入图片描述

在这里插入图片描述

xml方式
在这里插入图片描述
在这里插入图片描述
其中,constructor-arg标签name属性的值必须和构造函数中参数的名字相同!
同样的,普通属性直接通过value注入即可;
对象属性通过ref属性注入。
在这里插入图片描述

3、静态工厂的方法注入

静态工厂顾名思义,就是通过调用静态工厂的方法来获取自己需要的对象。
为了使用Spring的依赖注入IOC,我们不直接通过"工程类.静态方法()"来获取对象,而是依然通过spring注入的形式获取:

此种方式无通过注解注入
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4、实例工厂的方法注入

实例工厂的意思是获取对象实例的方法不是静态的,所以你需要首先new工厂类,再调用普通的实例方法:

此种方式无通过注解注入
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
另:------------------------------------------------------------------------------------------------------------------
在这里插入图片描述

@Component注解的作用

package com.jt.demo6;

import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * 第三天课程
 * Spring自动为该注解标识的类通过反射实例化对象,交给Spring容器管理.
 *  Key: 类名首字母小写 user
 *  value: 反射的对象
 *  类似于@Bean注解
 *
 *  @Component/@Bean区别:
 *  1.@Component spring容器通过反射自动创建对象
 *    @Bean     是用户自己手动创建对象
 *  2.@Component 标识类的
 *    @Bean   标识配置类中的方法
 *  3.@Component 对象的Id是类名首字母小写
 *    @Bean   对象的Id是方法名
 */
@Component
public class User {

    //1.对象的创建
    public User(){
        System.out.println("用户对象创建成功!!!");
    }

    //2.进行初始化操作
    @PostConstruct
    public void init(){
        System.out.println("为属性赋值!!!");
    }

    //3.进行业务调用  业务方法 用户手动调用!!!
    public void hello(){
        System.out.println("我爱学java");
    }

    //4.销毁方法
    @PreDestroy
    public void destroy(){
        System.out.println("调用销毁方法,释放资源!!!");
    }
}


@ComponentScan说明

  • 为了让Spring的注解生效. 需要单独使用包扫描注解.
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <description>Spring公共配置文件</description> <!-- mes 的數據庫 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/> <property name="jdbcUrl" value="jdbc:oracle:thin:@10.142.252.132:1521:mestest"/> <property name="maxPoolSize" value="10"></property> <property name="maxIdleTime" value="1800"></property> <property name="minPoolSize" value="1"></property> <property name="initialPoolSize" value="1"></property> <property name="properties"> <ref bean="mesDatasourcePropertiesFactory" /> </property> </bean> <!-- c3p0数据源的一个专有属性,只可以存放密码和用户名 --> <bean id="mesDatasourcePropertiesFactory" class="com.ccc.db.impl.DatasourcePropertiesFactory" factory-method="getProperties"> <!-- userName--> <constructor-arg type="java.lang.String"> <value>jxg/Qr4VbxU=</value> </constructor-arg> <!-- password --> <constructor-arg type="java.lang.String"> <value>jxg/Qr4VbxU=</value> </constructor-arg> <!-- 生产环境模式 ,才特殊处理加密密码--> <constructor-arg type="java.lang.String"> <value>true</value> </constructor-arg> </bean> <!-- ptc windchill的數據庫 --> <bean id="dataSourcePdm" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> <property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/> <property name="jdbcUrl" value="jdbc:oracle:thin:@10.142.252.132:1521:mesdev"/> <property name="maxPoolSize" value="10"></property> <property name="maxIdleTime" value="1800"></property> <property name="minPoolSize" value="1"></property> <property name="initialPoolSize" value="1"></property> <property name="properties"> <ref bean="ptcDatasourcePropertiesFactory" /> </property> </bean> <!-- c3p0数据源的一个专有属性,只可以存放密码和用户名 --> <bean id="ptcDatasourcePropertiesFactory" class="com.ccc.db.impl.DatasourcePropertiesFactory" factory-method="getProperties"> <!-- userName--> <constructor-arg type="java.lang.String"> <value>WgDH/SDIJfs=</value> </constructor-arg> <!-- password --> <constructor-arg type="java.lang.String"> <value>WgDH/SDIJfs=</value> </constructor-arg> <!-- 生产环境模式 ,才特殊处理加密密码--> <constructor-arg type="java.lang.String"> <value>true</value> </constructor-arg> </bean> <!-- mes數據源代理 --> <bean id="dataSourceProxy" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy" p:targetDataSource-ref="dataSource"/> <!-- 对web包中的所有类进行扫描,以完成Bean创建和自动依赖注入的功能--> <context:component-scan base-package="com.ccc"/> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" p:order="0" /> <!-- 配置事务管理器 針對MES數據庫--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager " p:dataSource-ref="dataSourceProxy"/> <!-- 配置事务的传播特性 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="add*" propagation="REQUIRED"/> <tx:method name="insert*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="*" read-only="true"/> </tx:attributes> </tx:advice> <!-- 那些类的哪些方法参与事务 --> <aop:config> <aop:pointcut id="allManagerMethod" expression="execution(* com.ccc..*.*(..))"/> <aop:advisor pointcut-ref="allManagerMethod" advice-ref="txAdvice"/> </aop:config> <!-- 配置事务管理器,這個事務性是爭對pdm數據庫的 --> <bean id="transactionManagerPdm" class="org.springframework.jdbc.datasource.DataSourceTransactionManager " p:dataSource-ref="dataSourcePdm"/> <!-- 配置事务的传播特性 --> <tx:advice id="txAdvicePdm" transaction-manager="transactionManagerPdm"> <tx:attributes> <tx:method name="add*" propagation="REQUIRED"/> <tx:method name="insert*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="*" read-only="true"/> </tx:attributes> </tx:advice> <!-- 那些类的哪些方法参与事务 --> <aop:config> <aop:pointcut id="allManagerMethodPdm" expression="execution(* com.ccc.pdm..*.*(..))"/> <aop:advisor pointcut-ref="allManagerMethodPdm" advice-ref="txAdvicePdm"/> </aop:config> <!-- ibatis插件 --> <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean" p:dataSource-ref="dataSourceProxy"> <property name="configLocation"> <value>classpath:SqlMapConfig.xml</value> </property> </bean> <bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate"> <property name="sqlMapClient"> <ref bean="sqlMapClient" /> </property> </bean> <!-- 配置要拦截的url,防止2次提交或做其他數據統計用 <bean id="doubleSubmitInterceptor" class="com.ccc.filter.DoubleSubmitInterceptor"> <property name="mappingURL" value=".html" /> <property name="viewURL" value=".html" /> </bean> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" p:order="0"> <property name="interceptors"> <list> <ref bean="doubleSubmitInterceptor"/> </list> </property> </bean> --> <!-- JDBC template注入及事務配置 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource"><ref bean="dataSourceProxy"/></property> </bean> </beans>
Spring-IOCSpring框架的核心部分之一,它是一种设计模式,全称为Inversion of Control(控制反转)。它通过将对象的创建、依赖关系的管理和对象的生命周期交给Spring容器来实现,从而降低了组件之间的耦合度,提高了代码的可重用性和可维护性。Spring-IOC的实现主要依靠Spring容器,Spring容器是Spring框架的核心,它负责创建、管理和装配Bean对象,其中Bean是Spring框架中最基本的组件。 Spring-IOC的实现主要有两种方式:BeanFactory和ApplicationContext。其中,BeanFactory是Spring-IOC的基本实现,而ApplicationContext是BeanFactory的子接口,提供了更多高级特性。ApplicationContextSpring框架中最常用的IOC容器,它除了提供BeanFactory的所有功能外,还提供了更多的企业级特性,例如AOP、事务管理、国际化、事件传播等。 下面是一个简单的Spring-IOC的例子,假设我们有一个UserService接口和一个UserServiceImpl实现类,我们可以通过Spring-IOC容器来创建和管理UserServiceImpl对象: 1.定义UserService接口和UserServiceImpl实现类 ```java public interface UserService { void addUser(User user); } @Service public class UserServiceImpl implements UserService { @Override public void addUser(User user) { // 添加用户的具体实现 } } ``` 2.在Spring配置文件中配置UserService实例 ```xml <bean id="userService" class="com.example.service.UserServiceImpl"/> ``` 3.在代码中获取UserService实例并使用 ```java ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = context.getBean("userService", UserService.class); User user = new User(); userService.addUser(user); ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值