二、Spring的核心之IoC(Inversion of Control 控制反转)

1、IoC是什么?

回顾:连接池原理中的使用。

注意:我们在连接池原理中是使用构造函数注入的,当然还可以通过提供set方法实现注入。

      

2、Spring容器

Spring容器简单理解就是用于存放对象的。

3、Spring的IoC入门

3.1、建立一个java工程

3.2、导入Spring的核心jar包

3.3、建立一个XML配置文件

 <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>

注意:现在xml文件用什么名字无所谓。

关于spring的xml文件没有提示的原因和解决办法,与struts2和hibernate中相同。只是引入的约束前两个是dtd,而spring引入的schema约束。

3.4、资源交给Spring容器管理

 <!-- 把持久层和业务层的创建都交给spring来管理
bean元素用于配置程序中可重用的组件。包括持久层,业务层以及表现层动作类
id属性指定的是spring容器中的key
class属性指定的就是类的全名称
spring容器在创建时,会读取配置文件,创建一个容器(map),把id作为key,把class属性创建的对象作为value,存入容器中 在加载配置文件时,会反射创建类对象。调用的默认无参的构造函数
-->
<bean id="userDao" class="cn.itcast.dao.impl.UserDaoForMySQLImpl"></bean> <bean id="userService" class="cn.itcast.service.impl.UserServiceImpl">
<!-- 在service中,注入dao -->
<property name="userDao" ref="userDao"></property>
</bean>

3.5、Spring容器的初始化及资源的获取

 public static void main(String[] args) {
/*
* 1.加载配置文件,用于创建spring的容器(map)
* ClassPathXmlApplicationContext:表示配置文件在类路径下
* FileSystemXmlApplicationContext():当配置文件不在类路径下,而是在磁盘上时,使用此类加载。
*/
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
//从容器中获取需要的对象:根据key取value
// IUserDao userDao = (IUserDao) ac.getBean("userDao");
// System.out.println(userDao);
IUserService userService = (IUserService) ac.getBean("userService");
System.out.println(userService);
userService.saveUser();
}

4、Spring中API的体系结构

4.1、核心接口和类

BeanFactory:它使用的是延迟加载思想。当我们需要用bean时,才去创建对象。

ApplicationContext:它继承自BeanFactory接口,还继承了很多其他接口。功能比BeanFactory强大。它用的不是延迟加载思想,而是在加载配置文件时就创建了。(推荐)

FileSystemXmlApplicationContext:配置文件在本地磁盘上,使用该类加载。

ClassPathXmlApplicationContext :配置文件在classpath中,使用此类加载。

5、基于XML的spring的IoC配置

5.1、Spring实例化bean的方式

调用默认的构造方法 (推荐)

 <!-- 把持久层和业务层的创建都交给spring来管理
bean元素用于配置程序中可重用的组件。包括持久层,业务层以及表现层动作类
id属性指定的是spring容器中的key
class属性指定的就是类的全名称
spring容器在创建时,会读取配置文件,创建一个容器(map),把id作为key,把class属性创建的对象作为value,存入容器中 需要掌握:在加载配置文件时,会反射创建类对象。调用的默认无参的构造函数。如果没有提供无参构造的情况下,是不能实例化bean对象的
-->
<bean id="userDao" class="cn.itcast.dao.impl.UserDaoForMySQLImpl"></bean> <bean id="userService" class="cn.itcast.service.impl.UserServiceImpl"></bean>

5.2、Bean的作用范围

 <!-- Bean的作用范围
scope属性:
取值:
singleton:单例(默认值)
prototype:多例
request:请求范围
session:会话范围
global-session:集群的会话范围。
-->
<bean id="userBean" class="cn.itcast.bean.UserBean1" scope="prototype">
</bean>

5.3、Bean的生命周期方法

 /**
* 模拟一个Bean
* @author zhy
*
*/
public class UserBean { //实例化
public UserBean(){
System.out.println("实例化:大爷来也!");
}
//初始化
public void init(){
System.out.println("初始化:大爷准备好了");
}
//销毁
public void destroy(){
System.out.println("销毁:老夫休矣!");
} public void saveUser(){
System.out.println("业务方法:老夫只劫财不劫色");
}
}
 <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- Bean的生命周期
bean默认情况下是单例的,但是没有执行销毁方法。
bean:出生 活着 死亡
出生:在使用立即加载方式,spring容器一创建,bean对象就已经都创建好了。实例化bean和初始化bean就都执行了。
活着:spring容器还在,bean对象就一直在。
死亡:spring容器如果没了,bean对象也就消亡了。
-->
<bean id="userBean" class="cn.itcast.bean.UserBean" init-method="init" destroy-method="destroy"></bean>
</beans>

注意:当非单例时,初始化方法正常执行,但是销毁方法就不会执行了。

5.4、依赖注入

a、构造器注入:通过传参数

 <!-- 第一种方式:是通过构造函数注入
使用construtor-arg
常用属性:
index:指定的是参数出现在构造函数中的索引
type:指定参数在构造函数中的数据类型
name:指定参数在构造函数中的名称 *****
以上三个都是在指定:给谁注入 value:注入基本数据类型或者String类型的值
ref:注入的是其他bean类型的值
以上两个都是在指定:注入的值 当在定义bean时,使用了constructor-arg元素,则在bean元素中有几个constructor-arg,就需要提供对应参数列表的构造函数
-->
<bean id="userBean" class="cn.itcast.bean.UserBean1">
<constructor-arg name="name" value="test" ></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="birthday" ref="now" ></constructor-arg>
</bean>

b、属性注入:推荐

 <!-- 第二种方式:是通过属性的set方法注入
需要使用的元素是:property
属性:
name:写的是set方法后面的部分,并且首字母转小写。
ref:注入的其他Bean类型的值
value:注入的是基本类型或者String类型的值
-->
<bean id="userBean2" class="cn.itcast.bean.UserBean2">
<property name="name" value="test" ></property>
<property name="age" value="18"></property>
<property name="birthday" ref="now"></property>
</bean>

c、p名称空间

 <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 使用p名称空间注入
1、导入P名称空间:xmlns:p="http://www.springframework.org/schema/p"
2、在bean元素中使用p名称空间
p:属性名称。
属性名称指的是set方法后面的部分。
每个属性都有两个赋值方式:
p:属性名称
p:属性名称-ref
-->
<bean id="userBean4" class="cn.itcast.bean.UserBean4" p:name="test" p:age="20" p:birthday-ref="now"></bean> <bean id="now" class="java.util.Date"></bean>

d、SpEL(Spring Expression Lanaguage)

 <!-- 使用Spring中EL表达式。SpringEL 目前定位:了解
${now}就是SPring的EL表达式
-->
<bean id="userBean3" class="cn.itcast.bean.UserBean3">
<property name="name" value="test" ></property>
<property name="age" value="18"></property>
<property name="birthday" value="#{now}"></property>
</bean>

e、注入集合数据

 <!-- 注入集合数据
如果是对象集合数据,list结构的,可以使用如下三个元素:
array
list
set
如果是map结构的,可以使用如下四个元素
map:
map的子元素是entry
props
props的子元素是prop
只要结构相同,元素可以互换。
-->
<bean id="userBean5" class="cn.itcast.bean.UserBean5">
<!-- 给数组注入值 -->
<property name="myStrs">
<list>
<value>AAA</value>
<value>BBB</value>
<value>CCC</value>
</list>
</property>
<!-- 给List集合注入值 -->
<property name="myList">
<set>
<value>AAA</value>
<value>BBB</value>
<value>CCC</value>
</set>
</property>
<!-- 给Set集合注入值 -->
<property name="mySet">
<array>
<value>AAA</value>
<value>BBB</value>
<value>CCC</value>
</array>
</property>
<!-- 给map注入数据 -->
<property name="myMap">
<props>
<prop key="testA">AAA</prop>
<prop key="testB">BBB</prop>
<prop key="testC">CCC</prop>
</props>
</property>
<!-- 给properties注入数据 -->
<property name="myProps">
<map>
<entry key="AAA">
<value>testA</value>
</entry>
<entry key="BBB" value="testB"></entry>
<entry key="CCC">
<value>testC</value>
</entry>
</map>
</property>

5.5、团队开发:多个Spring配置文件

a、一次加载多个配置文件

 public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("bean1.xml","bean2.xml");
//获取bean对象
UserBean1 bean1 = (UserBean1)ac.getBean("userBean1");
bean1.saveUser(); UserBean2 bean2 = (UserBean2)ac.getBean("userBean2");
bean2.saveUser();
}

b、基于主从配置文件

 <!-- Spring的多配置文件
引入其他的配置
-->
<import resource="bean1.xml"/>
<import resource="bean2.xml"/>

c、注意事项

同一个配置文件中不能出现bean元素id属性取值相同的:

不同文件中bean元素id属性取值相同时,有加载顺序

使用bean的name属性获取bean对象(了解就行)

6、基于注解的spring的IoC配置

6.1、注解的使用前提

a、引入context的名称空间

b、指定要扫描的包

c、在Bean上面加入@Component注解

 @Component("userBean")
//就相当于在配置文件中配置<bean id="userBean" class="cn.itcast.bean.UserBean" />
public class UserBean { @Value(value="test")
private String name; public void saveUser(){
System.out.println("业务方法:老夫只劫财不劫色");
System.out.println(name);
}
}

b、@Component的衍生注解@Controller@Service@Repository

作用:和@Component作用一样,让Spring容器管理(实例化)当前的bean。

属性: value:指定bean的名称。默认值是当前类的简单类名首字母小写

特点:在三成架构中,每个注解对应一层,使语义更加明确。

@Controller一般用在表现层,比如struts2action

@Service一般用在业务层,比如Service实现

@Repository一般用在持久层,比如Dao实现

 @Repository("userDaoForMySQL")
public class UserDaoForMySQLImpl implements IUserDao { public void saveUser() {
System.out.println("MySQL:保存了用户");
} public void deleteUser() {
System.out.println("MySQL:删除了用户");
} }
@Service("userService")
public class UserServiceImpl implements IUserService { public void saveUser() {
System.out.println("UserServiceImpl的savaUser方法执行了");
userDao.saveUser();
} public void deleteUser() {
userDao.deleteUser();
} }
@Controller("userAction")
public class UserAction { public String saveUser(){
System.out.println("UserAction的savaUser方法执行了");
userService.saveUser();
return null;
}
}

c、@Autowired

作用:自动按类型注入需要的对象。当使用了该注解时,setter就不是必须的了。

属性:

required:是否必须注入成功。默认值是true。

true:必须注入成功,如果出现注入失败,抛出异常。

false:不一定注入成功,不抛异常。

注意事项:

一个Service接口:IBookService

两个Service实现:BookServiceImpl1  BookServiceImpl2

由于@Autowired是自动按类型注入,当使用接口类型时,就看变量的名称,如果变量名称是bookServiceImpl1,则使用BookServiceImp1这个实现类,

如果变量名是bookServiceImpl2,则使用BookServiceImpl2这个实现类。如果没有符合规范的名称(类名首字母小写),则报错。

到底注入哪个实现类:

@Autowried

private BookService bookServiceImpl1;//注入BookServiceImpl1

@Autowried

private BookService bookServiceImpl2;//注入BookServiceImpl2

@Autowried

private BookService bookService;//注入失败

d、@Value

作用:注入基本类型和String。

属性:value:SpEL表达式,要注入的值

e、@Qualifier

作用:要配合@Autowried来一起使用,通过它指定要注入的bean的名称。按类型注入失效了。

属性:value:要注入的bean的名称

f、@Resource

作用:如同@Autowire和@Qualifier,是规范JSR-250中定义的(JCP)。通过指定bean的名称注入对象。

属性: name:要注入的bean的名称

g、@PostConstruct(了解)

作用:用在初始化方法上。生命周期有关

h、@PreDestroy(了解)

作用:用在销毁方法上。生命周期有关

i、@Configuration和@Bean(了解)

作用:@Configuration指定当前类为配置类,用于加载@Bean的定义。@Bean用于定义bean的名称,用法是@Bean(name="beanName")

注意:该类要被设置在注解自动扫描对应的包下。

6.3、Spring中使用单元测试

a、导入jar包:

spring-test-3.2.0.RELEASE.jar

b、设置Junit运行器和Spring配置文件

 /**
* Spring整合Junit
* 1、导入junit的jar包。导入spring整合junit的jar包
* 2、要替换运行器(其实就是测试用的main函数),换成spring框架提供的,因为只有spring框架提供的才能支持spring。
* 3、告知新运行器,spring的配置文件所在的位置
* @author zhy
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:bean.xml"})
public class UserBeanTest { @Autowired
private UserBean userBean; @Test
public void testSaveUser(){
userBean.saveUser();
}
}

Java实战之03Spring-02Spring的核心之IoC的更多相关文章

  1. [转载] JAVA面试题和项目面试核心要点精华总结(想进大公司必看)

    JAVA面试题和项目面试核心要点精华总结(想进大公司必看) JAVA面试题和项目面试核心要点精华总结(想进大公司必看)

  2. 「小程序JAVA实战」springboot的后台搭建(31)

    转自:https://idig8.com/2018/08/29/xiaochengxujavashizhanspringbootdehoutaidajian31/ 根据下面的图,我们来建立下对应的sp ...

  3. Java中对象的生与灭- 核心篇

    前言 大家好啊,我是汤圆,今天给大家带来的是<Java中对象的生与灭- 核心篇>,希望对大家有帮助,谢谢 文章纯属原创,个人总结难免有差错,如果有,麻烦在评论区回复或后台私信,谢啦 简介 ...

  4. Java实战:教你如何进行数据库分库分表

    摘要:本文通过实际案例,说明如何按日期来对订单数据进行水平分库和分表,实现数据的分布式查询和操作. 本文分享自华为云社区<数据库分库分表Java实战经验总结 丨[绽放吧!数据库]>,作者: ...

  5. Spring核心思想Ioc和Aop (面试)

    Spring核心思想Ioc和Aop (面试) 注意: Ioc和Aop并不是Spring提出的,在Spring之前就已经存在,Spring只是在技术层面给这两个思想做了非常好的实现. 1 Ioc 1.1 ...

  6. Java Spring Boot VS .NetCore (三)Ioc容器处理

    Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...

  7. Spring 核心之IOC 容器

    核心概念: IOC(Inversion of Control)控制反转:所谓控制反转,就是把原先我们代码里面需要实现的对象创建.依赖的代码,反转给容器来帮忙实现. DI(Dependency Inje ...

  8. Java实战之03Spring-03Spring的核心之AOP(Aspect Oriented Programming 面向切面编程)

    三.Spring的核心之AOP(Aspect Oriented Programming 面向切面编程) 1.AOP概念及原理 1.1.什么是AOP OOP:Object Oriented Progra ...

  9. 添物零基础到大型全栈架构师 Java实战及解析(实战篇)- 概述

    ​ 实战篇是在基础之上,进一步提升的内容.通过实战篇可以深入理解Java相关框架和库的使用,能够独立开发小模块,或者按照架构师的指导进行代码编写和完善. 主要讲解核心框架和库的使用和使用场景介绍.通过 ...

随机推荐

  1. 【Away3D代码解读】(三):渲染核心流程(渲染)

    还是老样子,我们还是需要先简略的看一下View3D中render方法的渲染代码,已添加注释: //如果使用了 Filter3D 的话会判断是否需要渲染深度图, 如果需要的话会在实际渲染之前先渲染深度图 ...

  2. ECSHOP文件目录详解

    ECShop 最新程序 的结构图及各文件相应功能介绍ECShop文件结构目录┣ activity.php 活动列表┣ affiche.php 广告处理文件┣ affiliate.php 生成商品列表┣ ...

  3. mybatis 打印sql log配置

    mybatis 打印sql log, 方便调试.如何配置呢? log4j.xml : <!-- 打印sql start --> <appender name="IBatis ...

  4. 基于EF创建数据库迁移

    通过创建的实体类和DbContext类利用EF的Code First数据库迁移创建数据库. 下面看代码. 一.先创建实体类 我先添加一个BaseEntity,里面就一个属性 [Key] public ...

  5. HBase 使用场景和成功案例

    有时候了解软件产品的最好方法是看看它是怎么用的.它可以解决什么问题和这些解决方案如何适用于大型应用架构,能够告诉你很多.因为HBase有许多公开的产品部署,我们正好可以这么做.本章节将详细介绍一些人们 ...

  6. jQuery生成二维条形码 jquery.qrcode.js

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  7. UART与USART的差别

    UART与USART都是单片机上的串口通信,他们之间的差别例如以下: 首先从名字上看: UART:universal asynchronous receiver and transmitter通用异步 ...

  8. PCL入门—点云操作 定义变量 显示点云 存储

    // 定义相关变量 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_ptr (new pcl::PointCloud<pcl::PointXYZ& ...

  9. android报错及解决1--Bitmap加载时,报bitmap size exceeds VM budget

    报错描述: 用Bitmap加载图片资源时,报错java.lang.OutOfMemoryError: bitmap size exceeds VM budget 原因分析: android系统限制,只 ...

  10. IOS - UIImage

    IOS中对图片的处理 UIImage UIImage 继承于NSObject 以下介绍一下UIImage中的方法 首先是我们最经常使用的 通过图片的文件名称来获取这个图片 + (UIImage *)i ...