Java实战之03Spring-02Spring的核心之IoC
二、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:一般用在表现层,比如struts2的action上
@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的更多相关文章
- [转载] JAVA面试题和项目面试核心要点精华总结(想进大公司必看)
JAVA面试题和项目面试核心要点精华总结(想进大公司必看) JAVA面试题和项目面试核心要点精华总结(想进大公司必看)
- 「小程序JAVA实战」springboot的后台搭建(31)
转自:https://idig8.com/2018/08/29/xiaochengxujavashizhanspringbootdehoutaidajian31/ 根据下面的图,我们来建立下对应的sp ...
- Java中对象的生与灭- 核心篇
前言 大家好啊,我是汤圆,今天给大家带来的是<Java中对象的生与灭- 核心篇>,希望对大家有帮助,谢谢 文章纯属原创,个人总结难免有差错,如果有,麻烦在评论区回复或后台私信,谢啦 简介 ...
- Java实战:教你如何进行数据库分库分表
摘要:本文通过实际案例,说明如何按日期来对订单数据进行水平分库和分表,实现数据的分布式查询和操作. 本文分享自华为云社区<数据库分库分表Java实战经验总结 丨[绽放吧!数据库]>,作者: ...
- Spring核心思想Ioc和Aop (面试)
Spring核心思想Ioc和Aop (面试) 注意: Ioc和Aop并不是Spring提出的,在Spring之前就已经存在,Spring只是在技术层面给这两个思想做了非常好的实现. 1 Ioc 1.1 ...
- Java Spring Boot VS .NetCore (三)Ioc容器处理
Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...
- Spring 核心之IOC 容器
核心概念: IOC(Inversion of Control)控制反转:所谓控制反转,就是把原先我们代码里面需要实现的对象创建.依赖的代码,反转给容器来帮忙实现. DI(Dependency Inje ...
- Java实战之03Spring-03Spring的核心之AOP(Aspect Oriented Programming 面向切面编程)
三.Spring的核心之AOP(Aspect Oriented Programming 面向切面编程) 1.AOP概念及原理 1.1.什么是AOP OOP:Object Oriented Progra ...
- 添物零基础到大型全栈架构师 Java实战及解析(实战篇)- 概述
实战篇是在基础之上,进一步提升的内容.通过实战篇可以深入理解Java相关框架和库的使用,能够独立开发小模块,或者按照架构师的指导进行代码编写和完善. 主要讲解核心框架和库的使用和使用场景介绍.通过 ...
随机推荐
- Packetbeat协议扩展开发教程 一
原文链接:http://elasticsearch.cn/article/48 Packetbeat(https://www.elastic.co/products/beats/packetbeat) ...
- JavaScript要点(十三) HTML DOM EventListener
addEventListener() 方法 <body> <p>该实例使用 addEventListener() 方法在按钮中添加点击事件. </p> <bu ...
- 升级SUSE Linux内核的完整步骤!
http://blog.sina.com.cn/s/blog_491529d60100061h.html 安装完SLED 10后发现仍然有“热启动网络不通”的问题,原因是内核版本较低,于是升级到2.6 ...
- 创建性能监视器(logman)
在本地计算机上抓取性能信息 Logman.exe create counter Perf-1Second -f bincirc -max 500 -c "\Processor(*)\% Pr ...
- IOS开发之类和对象
IOS开发之类和对象 OC和Java一样都是一种面向对象的语言,从今天開始我和大家一起来系统学习这样的面向对象的语言oc,欢迎大家什么问题和我一起探讨和学习. OC定义类有两个步骤:1.接口部分(通俗 ...
- C++容器类对象函数參数问题
总之中的一个句话:容器类对象作为函数參数,与整数类型作为函数參数的传递特性同样. 验证程序 #include "stdafx.h" #include <iostream> ...
- IOS笔记 #pragma mark的用法
简单的来说就是为了方便查找和导航代码用的. 下面举例如何快速的定位到我已经标识过的代码. #pragma mark 播放节拍器 - (void) Run:(NSNumber *)tick { //.. ...
- J2EE的13个规范之(三) Servlet简单介绍
Servlet是一种server端脚本,它是一个特殊的Java类,继承自HttpServlet.开发中主要用于处理和响应client的请求. Servlet在容器中执行,事实上例的和销毁创建由容器进行 ...
- Database and models
Database and models The database Now that we have the Album module set up with controller action met ...
- SQL Abstraction and Object Hydration
SQL Abstraction and Object Hydration In the last chapter, we introduced database abstraction and a n ...