Spring入门(一)— IOC、DI
一、Spring介绍
Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。
Spring是2003年兴起的一个轻量级的java框架, 由 Rod Johnson 在其编著的《Expert one on one J2EE design and development》一书中阐述的思想和理念衍生而来。
Spring 有两个核心 IOC & aop
IOC
IOC 的全称是 Inversion Of Control 翻译过来是控制反转的意思。 把对象的创建工作交给框架来完成
UserService userService = new UserServiceImpl(); ---> 问框架要对象
AOP
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程

1. IOC的演变
从早期的直接new具体类 ---> 面向接口编程


面向接口编程 --使用工厂


使用Spring来替代


2. Spring入门
导入jar包
beans|code|context|expression4个日志jar包 , log4j.properties编写业务逻辑类
public interface UserService {
void save();
}
public class UserServiceImpl implements UserService {
@Override
public void save(){
System.out.println("调用了UserServiceImpl的save方法~!~!");
}
}
ml托管业务逻辑类
在src下,创建一个xml, 名字随意。 applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<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 id="us" class="com.pri.service.impl.UserServiceImpl"></bean> </beans>
创建工厂,问工厂要对象
public class MainTest {
@Test
public void testSave(){
/*
UserService userService = new UserServiceImpl();
userService.save();*/
//1. 创建工厂
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2. 问工厂要实例对象
UserService userService =(UserService) context.getBean("us");
//3. 调用方法
userService.save();
}
}
3. 配置详解
xml解释
<!-- bean 标签是用来告诉spring,需要帮忙创建什么类的实例
id | name : 标识符 , 以后拿着id的值就能问spring要对应类的实例。
class : 托管类的全路径
scope: 用于表示生成的实例模式
spring默认生成的实例是单例。 scope="prototype" 表示生成多例
init-method: 生成实例之后,调用的方法
destroy-method: 销毁实例的时候调用的方法
-->
<bean id="us" class="com.pri.service.impl.UserServiceImpl" scope="prototype"
init-method="init" destroy-method="destroy">
</bean>
代码解释
public class MainTest {
@Test
public void testSave(){
/*
UserService userService = new UserServiceImpl();
userService.save();*/
//1. 创建工厂 , 需要告诉工厂,xml文件在哪里。 不会这么写
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2. 问工厂要实例对象 , 可以让工厂送过来
UserService userService =(UserService) context.getBean("us");
//3. 调用方法
userService.save();
//关闭工厂 以后一般不关闭工厂
((AbstractApplicationContext) context).close();
}
}
二、IOC实例化方式
把对象交给spring创建的方式
1. 无参构造方法【重点】
要求托管类的务必提供无参构造方法,当然以后可以配置让spring走有参构造
代码
public class UserServiceImpl implements UserService {
//spring创建实例, 要求托管类默认提供无参构造方法。
@Override
public void save(){
System.out.println("调用了UserServiceImpl的save方法~!~!");
}
}
配置
<?xml version="1.0" encoding="UTF-8"?>
<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 id="us" class="com.pri.service.impl.UserServiceImpl"></bean>
</beans>
2. 静态工厂方法【了解】
要求提供工厂类,并且工厂的方法是静态方法, 在方法里面生成业务逻辑类的实例
代码
public class StaticFactory {
public static UserService getBean(){
System.out.println("要创建UserServiceImpl的实例了~~");
return new UserServiceImpl();
}
}
xml
<!-- 我们也是拿着us去问spring工厂要实例, 它直接就调用了StaticFactory的getBean方法拿到实例,然后返回 -->
<!-- 静态工厂配置 -->
<bean id="us" class="com.pri.factory.StaticFactory" factory-method="getBean"></bean>
3. 实例工厂方法【了解】
代码
public class InstanceFactory {
public UserService getBean(){
System.out.println("要创建UserServiceImpl的实例了~~");
return new UserServiceImpl();
}
}
xml
<bean id="factory" class="com.pri.factory.InstanceFactory"/>
<bean id="us" factory-bean="factory" factory-method="getBean"></bean>
后面的两种工厂的配置,开发当中几乎不会用。
三、依赖注入
什么是依赖注入?
DI : 全称是 dependency Injection 翻译过来是依赖注入 本意是在实例化对象的时候,对它里面的成员属性进行值的注入。
public class UserServiceImpl{
private String name;
//1. set方法
public void setName(String name){
this.name=name;
}
}
UserServiceImpl us = new UserServiceImpl();
us.setName("zhangsan");
//现在实例的创建是工厂来完成,我们想让工厂创建实例的时候,顺便把成员变量给赋值了。
给成员变量赋值的方式【DI的方式】
①set方法
②有参构造
1. 依赖注入的方式【重点】
注入的方式有两种: 有参构造 | set方法
1. 采用有参构造完成依赖注入
提供有参构造方法
代码
public class UserServiceImpl implements UserService {
private String address;
public UserServiceImpl(String address) {
super();
this.address = address;
}
@Override
public void save(){
System.out.println("调用了UserServiceImpl的save方法~!~!=="+address);
}
}
xml
<bean id="us" class="com.pri.service.impl.UserServiceImpl" >
<!-- 指定构造的参数, name: 参数的名称, values: 参数的值 -->
<constructor-arg name="address" value="深圳"/>
</bean>
2. 采用set方法完成依赖注入
代码
public class UserServiceImpl implements UserService {
private String address;
public void setAddress(String address) {
this.address = address;
}
@Override
public void save(){
System.out.println("调用了UserServiceImpl的save方法~!~!=="+address);
}
}
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"> <bean id="us" class="com.pri.service.impl.UserServiceImpl" >
<property name="address" value="宝安"/>
</bean>
</beans>
2. 注入数据类型的演练
1. 集合类型
a. 数组类型
代码
public class UserServiceImpl implements UserService{
private String [] address;
public void setAddress(String [] address) {
this.address = address;
}
...
}
xml
<property name="address" >
<array>
<value>北京1</value>
<value>北京2</value>
<value>我爱北京天安门,天安门很大</value>
</array>
</property>
b. list集合
代码
public class UserServiceImpl implements UserService{
private List<String> address;
public void setAddress(List<String> address) {
this.address = address;
}
...
}
xml
<property name="address">
<list>
<value>北京1</value>
<value>北京2</value>
<value>我爱北京天安门,天安门很大</value>
</list>
</property>
c. map集合
代码
public class UserServiceImpl implements UserService{
private Map<String ,Object> address;
public void setAddress( Map<String ,Object> address) {
this.address = address;
}
...
}
xml
<property name="address">
<map>
<entry key="地址1" value="北京1"/>
<entry key="地址2" value="北京2"/>
<entry key="地址3" value="北京3"/>
</map>
</property>
2. 对象类型
代码
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save(){
System.out.println(" ==调用了UserServiceImpl的save方法~!~!==");
/*UserDao userDao =new UserDaoImpl(); //创建对象 ---》 IOC ----> bean标签
userDao.save();*/
//1. 我们自己创建对象,然后自己用。
//2. 工厂创建对象,我们去问它要对象
//3. 工厂创建对象,让工厂自己送过来对象。 --- 》 注入对象
userDao.save();
}
}
xml
<!-- 让spring创建UserServiceImpl的实例 -->
<bean id="us" class="com.pri.service.impl.UserServiceImpl" > <!-- 让spring调用UserServiceImpl的setUserDao的方法,并且把刚才创建好的ud的那个实例当成参数,传递进去。
这就完成了对象的注入 -->
<property name="userDao" ref="ud"></property>
</bean> <!-- 让spring创建UserDaoImpl的实例 -->
<bean id="ud" class="com.pri.dao.impl.UserDaoImpl"></bean>
3.注入的xml写法细节【了解】
依赖注入的方式已经固定化了,就是 有参构造 | set方法。 但是spring担心程序员在xml的配置要写的代码很多,然后程序员就不喜欢用了。所以spring针对xml的注入,提出了两种简化写法 : p 名称空间 | c名称空间
p 名称空间
针对的是这个
<property name="" />, 也就表明了代码里面声明注入的方式是 set方式
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="us" class="com.pri.service.impl.UserServiceImpl" p:address="北京">
</bean>
c 名称空间
针对的是这个
<constructor-arg/>, 也就要求我们的代码声明注入的方式必须是有参构造
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="us" class="com.pri.service.impl.UserServiceImpl" c:address="北京">
</bean>
SPEL 属性注入
可以完成逻辑运算
<bean id="us" class="com.pri.service.impl.UserServiceImpl" >
<property name="address" value="#{1>2}"/>
</bean>
四、整合Servlet
1. 初步整合
在servlet里面创建工厂、然后获取实例对象
public class ServletDemo extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("调用了get方法~~~");
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService us = (UserService)context.getBean("us");
us.save();
((AbstractApplicationContext) context).close();
}
}
2. 初步整合的问题
2个问题
1. 每次请求过来都会解析xml, 创建工厂。如果xml内容很多,就比较的耗时。
解决方法:
工具类 | 静态代码块 2. 工厂创建的时机有点晚。 第一次使用的时候才会创建。
解决方法:
提前创建 --- 提前到项目发布 --- 项目发布之后,就会创建一个类的实例(ServletContext)-----ServletContextListner
a. 如果是我们自己处理的, 定义监听器, 然后在监听器里面创建工厂 , 存储工厂到一个地方去,以便所有的servlet都能使用到工厂。 servletContext.
b. 监听器不用你们写了,工厂创建的代码不用你们写了。放到servletcontext也不用写了。 配置监听器。
3. 进阶整合
把上面出现的问题给解决掉 ,必须要导入额外的jar包
spring-web-xxx.jar只要项目一发布,就立即创建工厂,那么我们必须的抓住项目发布的这个契机。 以前在servlet阶段,学过一种东西监听器 ,可以监听作用域对象的创建与销毁 , SerlvetContext, 这是最大的作用域,全局只有一个对象。
在web.xml 中配置 监听器 并且配置param 指定spring配置文件所在
<!-- 配置listener,目的就是让项目发布的回收,能够创建工厂。但是创建工厂
需要解析xml文件,它默认回到/WEB-INF/applicationContext.xml
要是找不到就报错,除非我们告诉它,xml文件在哪里 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!-- 告诉listener, 配置文件在哪里 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
通过工具类获取之前创建好的工厂
public class ServletDemo extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("调用了get方法~~~");
//ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
UserService us = (UserService)context.getBean("us");
us.save();
//((AbstractApplicationContext) context).close();
}
...
}
Spring入门(一)— IOC、DI的更多相关文章
- Spring入门2. IoC中装配Bean
Spring入门2. IoC中装配Bean 20131125 前言: 上一节学习了Spring在JavaProject中的配置,通过配置文件利用BeanFactory和ApplicationConte ...
- Spring入门1. IoC入门实例
Spring入门1. IoC入门实例 Reference:Java EE轻量级解决方案——S2SH 前言: 之前学习过关于Spring的一点知识,曾经因为配置出现问题,而总是被迫放弃学习这些框架技术, ...
- Spring入门导读——IoC和AOP
和MyBatis系列不同的是,在正式开始Spring入门时,我们先来了解两个关于Spring核心的概念,IoC(Inverse of Control)控制反转和AOP()面向切面编程. 1.IoC(I ...
- Spring入门 (IOC)
1.实现原理
- Spring入门及IoC的概念
Spring入门 Spring是一个轻量级的Java开发框架,最早由Robd Johnson创建,目的为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题,它是一个分层的JavaSE/EE轻量级开源 ...
- Spring入门之IOC
IOC/DI: Spring最核心的灵魂,IOC/DI(控制反转/依赖注入)!,这里一定要理解他,理解这个思想.我会细说什么是IOC/DI.他的思想是什么.它带来了那些好处. 进入正题,先说说什么是i ...
- 十七、Spring框架(IOC/DI)
一.Spring框架 Spring是一个基于IOC和AOP的结构J2EE系统的框架. 1.IOC反转控制是Spring的基础(Inversion Of Control).也就是说创建对象由以前的程序员 ...
- spring中的IOC/DI的知识点
IOC(Inverse of control):控制反转;其实就是一个装对象的容器,以前我们在controller中调用service中的方法,都要先new 一个service对象,这样不符合模式设计 ...
- Spring.Net---3、IoC/DI深入理解
------------------------------------------------------------------------ 理解IoC/DI 1.控制反转 --> 谁控制谁 ...
- JAVAWEB 一一 框架整合(SSH,Spring+Struts2+Hibernate IOC/DI AOP声明式事务处理 定时任务)
package org.springframework.orm.hibernate3; import java.io.Serializable; import java.util.List; impo ...
随机推荐
- 代码审计就该这么来3 beescms getshell
本文作者:i春秋作家——索马里的海贼 前言上一回(http://bbs.ichunqiu.com/thread-13714-1-1.html)说到快速漏洞挖掘中的几个重点关注对象,命令执行,文件操作, ...
- dbus-launch(转)
*NAME* dbus-launch - Utility to start a message bus from a shell script dbus-launch - 从shell脚本启动一个消息 ...
- var 是 Java 开发的好朋友啊!
简评:Java var != JavaScript var. Java 10 中引入了新的语法用于局部变量类型推断,很多开发者有所疑惑,希望这篇文章能帮到你. 什么是类型推断 其实在 Java 中类型 ...
- [转]CocoaPods安装和使用教程
[转载自:http://code4app.com/article/cocoapods-install-usage] 目录 CocoaPods是什么? 如何下载和安装CocoaPods? 如何使用Coc ...
- iOS学习笔记(5)——显示简单的TableView
1. 创建工程 创建一个新的Xcode工程命名为SimpleTableTest. 删除main.storyboard文件和info.plist中有关storyboard的相关属性. 按command+ ...
- find查找文件命令 - Linux系统中的常用技巧整理
“find”在Linux系统中是比较常用的文件查找命令,使用方法有很多,可以拥有查找文件.文件目录.文件更新时间.文件大小.文件权限及对比文件时间.下面是整理的“find”常用方法,方便以后需要的时候 ...
- JDK源码分析(10) ConcurrentLinkedQueue
概述 我们要实现一个线程安全的队列有两种实现方法一种是使用阻塞算法,另一种是使用非阻塞算法.使用阻塞算法的队列可以用一个锁(入队和出队用同一把锁)或两个锁(入队和出队用不同的锁)等方式来实现,而非阻塞 ...
- [转] Akka 使用系列之二: 测试
[From] http://www.algorithmdog.com/akka-test 通过上一篇文章,我们已经大致了解怎么使用 Akka,期待细致用法.这篇文章将介绍如何用 Akka-testki ...
- header请求头信息详细介绍
https://www.byvoid.com/zhs/blog/http-keep-alive-header HTTP协议头部与Keep-Alive模式详解 1.什么是Keep-Alive模式? 我们 ...
- 使用nginx反向代理jenkins
1.在Jenkins 官方网站(http://jenkins-ci.org/)下载最新版本war包.拷贝到 $TOMCAT_HOME/webapps 下(不用解压).启动tomcat服务. 2.找到n ...