`

ioc

阅读更多
IOC的概念,分类
1.IOC设计原则:高层的抽象的模块不应该倚赖于底层的具体实现,抽象不倚赖于实现
问题:耦合性高,不利于维护
对象的倚赖关系交给容器建立
解决:
对象的倚赖关系交给容器建立
在运行时动态地建立
IOC的特点:
1.模块之间的耦合性降低
2.利于测试
IOC的分类:如何实现IOC?
1.基于setter方法
2.基于构造器
Demo1:
IDevice.java
package ioc;
public interface IDevice {
public void print();
}

NetworkDevice.java
package ioc;
public class NetworkDevice implements IDevice {
public void print() {
System.out.println("NetworkDevice's print()");
}
}

PrinterDevice.java
package ioc;
public class PrinterDevice implements IDevice {
public void print() {
System.out.println("PrinterDevice's print()");
}
}

BankService.java
package ioc;
public class BankService {
private IDevice device;
// 1.基于setter方法
public void setDevice(IDevice dev) {
this.device = dev;
}
public void report() {
System.out.println("BankService's report()");
device.print();
}
}

Factory.java
package ioc;
public class Factory {
// 通过配置文件
private static Factory instance = new Factory();
private BankService bs = null;
private IDevice device = null;
private Factory() {
bs = new BankService();
String className = ConfigUtil.getValue(IDevice.class.getSimpleName());
try {
device = (IDevice)Class.forName(className).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
bs.setDevice(device);
}

public static Factory getInstance() {
return instance;
}
public BankService getBankService() {
return bs;
}
}

ConfigUtil.java
package ioc;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class ConfigUtil {
private static Properties props = new Properties();
static {
InputStream ips = ConfigUtil.class.getClassLoader()
.getResourceAsStream("ioc/config.properties");
try {
props.load(ips);
} catch (IOException e) {
e.printStackTrace();
}
}
public static String getValue(String key) {
return props.getProperty(key);
}
public static void main(String[] args){
System.out.println(getValue("IDevice"));
}
}

config.properties
#IDevice=ioc.PrinterDevice
Idevice=ioc.NetworkDevice
Test.java
package ioc;
public class Test {
public static void main(String[] args){
BankService bankService = Factory.getInstance().getBankService();
bankService.report();
}
}
输出:
BankService's report()
NetworkDevice's print()
二.基本装配
IOC的基本使用
1.set方式的装配
2.构造器方式的装配
3.比较两种装配方式的区别
1.set方式的装配
(1).Bean类(pojo类)
(2).容器(Application Context)
(3).配置文件(*.xml)
常用的jar包:
spring/spring-framework-2.5.6/dist/spring.jar
spring/spring-framework-2.5.6/lib/cglib/cglib-nodep-2.1_3.jar
spring/spring-framework-2.5.6/lib/jakarta-commons
spring/spring-framework-2.5.6/aspectj标注时用到
spring/spring-framework-2.5.6/samples/jpetstore示例
spring/spring-framework-2.5.6/src源代码
Demo2:
第一步:建spring lib库
Window->Preferences->Java->Build Path->User Libraries->New
Spring2.0
把下面的jar包加到Spring2.0里面
spring/spring-framework-2.5.6/dist/spring.jar
spring/spring-framework-2.5.6/lib/cglib/cglib-nodep-2.1_3.jar
spring/spring-framework-2.5.6/lib/jakarta-commons
第二步:New Java Project (Project name:spring_ioc1)->Create separate source and output folders->ok
第三步:project->右键->MyEclipse->Add Spring Capabilities->(Spring2)User Libraries(spring2.0)-
>next->finish
在src下建立包ioc1.ioc1下建立类HelloBean.java和applicationContext.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-2.0.xsd">
<!-- (1)bean的id属性必须是唯一标志,不能重复 ,(2)必须符合xml的规范,比如不
能包含"/",如果有用name属性来代替id属性,class对应的完整的类名(ioc1.HelloBean)
-->
<!---Bean类:(1)如果采用setter方式装配必须提供一个公开的不带参的构造器
(2)对于需要装配的属性必须提供对应的setter方法(采用setter方式装配)

(3)对于客户端的代码ClassPathXmlApplicationContext的类文件应依据classpath来存放
->
<bean id="helloBean" class="ioc1.HelloBean">
<!-- name对应类HelloBean的属性name-->
<property name="name">
<value>zs</value>
</property>
</bean>
</beans>
HelloBean.java
package ioc1;
/**
* Bean类
* @author wangxiuwei
* @date 2010.10.13
*/
public class HelloBean {
private String name;
public void setName(String name) {
this.name = name;
}
public String sayHello() {
return "hello" + name;
}
}
Test.java
package ioc1;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 测试类
*@author wangxiuwei
* @date 2010.10.13
*/
public class Test {
public static void main(String[] args) {
// ioc1\\applicationContext.xml其中"\\"平台无关
// 构造了spring的容器,读取配置文件,
ApplicationContext ac = new ClassPathXmlApplicationContext(
"ioc1\\applicationContext.xml");
// 去找helloBean,根据id="helloBean" 找到class="ioc1.HelloBean",执行该类
// 并且把属性name="name" 的值 value=zs 通过setName给类赋值zs
HelloBean hb = (HelloBean) ac.getBean("helloBean");

// 找到后调用相应的方法
String str = hb.sayHello();
System.out.println(str);
}
}
Set方式装配
1.基本类型:8种基本类型 + 字符串
使用<value></value>元素
使用<property name="属性名">
<value>值</value>
</property>
<value>值</value>自动进行数据类型的转换
示例: (1)<property name="years">
<value>100</value>
</property>
此处也可以简化如下方式
(2)<property name="years" value="1000" />
2.对象类型的装配有如下三种方式
A <ref local>
B <ref bean>
C 直接嵌套
第一种情况
<!-- bean的id属性必须是唯一标志,不能重复 class对应的完整的类名 -->
//id="otherBean"与<ref local="otherBean" />
只在单前配置中查找
<bean id="otherBean" class="ioc2.otherBean">
<property name="obStr" value="String1"/>
</bean>
<bean id="someBean" class="ioc2.someBean">
<property name="ob">
<ref local="otherBean" />
</property>
</bean>
</beans>

对应的类中一定要有setXXX方法与该属性名对应
OtherBean SomeBean
只在当前配置文件中查找
第二种情况
<bean id="someBean" class="ioc2.SomeBean">
<property name="ob">
<bean id="otherBean" class="ioc2.OtherBean">
<property name="obStr" value="String1"/>
</bean>
</property>
</bean>
注:
1.不能够被客户端直接调用
2.某个Bean不希望被客户直接调用时,可以考虑把一个Bean定义在另外一个
Bean中
第三种情况
applicationContext.xml
<bean id="someBean" class="ioc2.SomeBean">
<property name="ob">
<ref bean="otherBean" />
</property>
</bean>
other.xml
<bean id="otherBean" class="ioc2.OtherBean">
<property name="obStr" value="String1"/>
</bean>
第四种情况
applicationContext.xml
<bean id="someBean" class="ioc2.SomeBean">
<!-- <property name="ob">
<ref bean="otherBean" />
</property>
与下面相同
-->
<property name="ob" ref="otherBean" />
</bean>
other.xml
<bean id="otherBean" class="ioc2.OtherBean">
<property name="obStr" value="String1"/>
</bean>
3.集合类型装配
List.Set,Map,Properties
applicationContext.xml
<bean id="someBean" class="ioc3.SomeBean">

<property name="listProperties">
<list>
<value>String1</value>
<value>String1</value>
<value>String3</value>
</list>
</property>
<property name="setProperties">
<set>
<value>String1</value>
<value>String1</value>
<value>String3</value>
</set>
</property>
<property name="mapProperties">
<map>
<entry key="mapKey">
<value>mapValue</value>
</entry>
</map>
</property>
<property name="props">
<props>
<prop key="propKey">propValue</prop>
</props>
</property>
</bean>
SomeBean.java
package ioc3;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class SomeBean {
private List listProperties;
private Set setProperties;
private Map mapProperties;
private Properties props;
public void setProps(Properties props) {
this.props = props;
}
public void setListProperties(List listProperties) {
this.listProperties = listProperties;
}
public void printInfo() {
System.out.println("listProperties:");
System.out.println(listProperties);
System.out.println("setProperties:");

System.out.println(setProperties);
System.out.println("mapProperties:");
System.out.println(mapProperties);
System.out.println("props:");
System.out.println(props);
}
public void setMapProperties(Map mapProperties) {
this.mapProperties = mapProperties;
}
public void setSetProperties(Set setProperties) {
this.setProperties = setProperties;
}
}
Test.java
package ioc3;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
// ioc2\\applicationContext.xml其中"\\"表示平台无关(不论是windows还是linux.unix都可以这样
用)
// 构造了spring的容器,读取配置文件,
ApplicationContext ac = new ClassPathXmlApplicationContext("ioc3\\applicationContext.xml");
SomeBean sb = (SomeBean) ac.getBean("someBean");
// 找到后调用相应的方法
sb.printInfo();
}
}
输出结果:
listProperties:
[String1, String1, String3]
setProperties:
[String1, String3]
mapProperties:
{mapKey=mapValue}
props:
{propKey=propValue}

2.构造器方式的装配
使用Constructor
applicationContext.xml
<bean id="otherBean" class="ioc4.OtherBean">
<property name="obStr">
<value>Andy</value>
</property>
</bean>
10
<bean id="someBean" class="ioc4.SomeBean">
<constructor-arg index="1">
<value>String1</value>
</constructor-arg>
<constructor-arg index="0">
<value>String2</value>
</constructor-arg>
<constructor-arg index="2">
<value>521521</value>
</constructor-arg>
<constructor-arg index="3">
<ref bean="otherBean" />
</constructor-arg>
</bean>

SomeBean.java
package ioc4;
public class SomeBean {
private String str1;
private String str2;
private int value1;
private OtherBean ob;
public SomeBean(String str1, String str2, int value1, OtherBean ob) {
// super();
this.str1 = str1;
this.str2 = str2;
this.value1 = value1;
this.ob = ob;
}
public void printInfo() {
System.out.println("str1: " + str1 + "str2: " + str2 + "value1: "
+ value1 + "ob: " + ob);
}
}
OtherBean.java
package ioc4;
11
public class OtherBean {
private String obStr;
public void setObStr(String obStr) {
this.obStr = obStr;
}
@Override
public String toString() {
return "OtherBean " + obStr;
}
}
Test.java
package ioc4;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext(
"ioc4\\applicationContext.xml");
SomeBean sb = (SomeBean) ac.getBean("someBean");
sb.printInfo();
}
}
要求:
1.Address采用构造器方式装配
2.person采用Set方式装配
3.打印personInfo
3 .set方式与constructor方式区别(有缺点<1>循环倚赖问题<2>属性很多,???????????构造器)
1.优先选set方式
2.bean的属性不错,
要求bean的属性在构造bean的实例时就已经完成装配,属性值在装配完后,就不再改变,
要求
Client通过Spring容器获得Bankservice实例,并且调用report()方法

三.复杂装配
1.Bean的定义的继承
Bean的配置信息可以复用
两个属性: 一是:abstract 两个值true,false,默认值是false
二是:parent
第一种情况:
1.配置文件applicationContext.xml
一般情况下保留abstract="true"
<bean id="abstractStudent" class="ioc7.Student" abstract="true">
<property name="className" value="sd0809" />
<property name="schoolName" value="tarena" />
</bean>
<bean id="student1" parent="abstractStudent">
<property name="name" value="张三" />
</bean>
<bean id="student2" parent="abstractStudent">
<property name="name" value="李四" />
</bean>
2.Student.java
package ioc7;
/**
* 学生类,采用setter方式进行装配
*
* @author wangxiuwei
* @date 2010.10.13
*/
public class Student {
@Override
public String toString() {
return name + " " + schoolName + " " + className;
}
private String name;
private String schoolName;
private String className;
public void setClassName(String className) {
this.className = className;
}
public void setName(String name) {
this.name = name;
}
public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}
}
3.Test.java
package ioc7;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* 测试类
* @authorwangxiuwei
* @date 2010.10.13*/
public class Test {
public static void main(String[] args){
ApplicationContext ac = new
ClassPathXmlApplicationContext("ioc7\\applicationContext.xml");
Student stu = (Student)ac.getBean("student1");
// Student stu = (Student)ac.getBean("student2");
System.out.println(stu);
}
}
第二种情况:
<!-- 优化配置文件 -->
<bean id="abstractBean" abstract="true">
<property name="str1" value="string1" />
</bean>
<bean id="b" class="ioc7.B" parent="abstractBean">
<property name="value1" value="100" />
</bean>
<bean id="a" class="ioc7.A" parent="abstractBean">
<property name="amt" value="20.33" />
</bean>
2.Bean scoping(Bean的范围)
Spring容器如何去管理Bean的生命周期,它有Bean的范围决定
5种范围如下:
(1)singleton(单例模式)默认是单例模式
(2)prototype
每次调用getBean("myBean");返回的都是myBean对象类型的一个新创建的对象.
(3)request
在一次HTTP请求中,一个bean定义对应一个实例.
(4)session
在一个HTTPsession中,一个bean定义对应一个实例.
(5)global-session
在一个全局的HTTPsession中,一个bean定义对应一个实例.
3.Autowiring (自动装配)
手动装配:<property name="ob" ref="otherBean" />
自动装配:<bean id="someBean" autowire="byName">
Autowiring Properties(规则):
1.autowire="byName"
Bean identifier matches property name
:此选项将检查属性名并查找id值和其相同的bean,将其注入
2.autowire="byTpe"
Type matcher other defined bean
:如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配
3.autowire="constructor"
Match constructor argument types
4.autowire="autodetect"
Attempt by constructor,otherwise"type"如果有默认的缺省构造器,会先尝试
setter"byType",否则,有自定义的带参的构造器则去"Constructor"
Spring IOC容器可以自动装配互相协作bean之间的倚赖关系,也就是,通过使用autowire,我
们就不需要象前面的配置文件那样显示指定要注入的简单值或者bean,
15
SomeBean OtherBean
ob
细节:
1.手动装配与自动装配可以结合使用
2.自动装配方式有个缺点,容易出错,正式开发一般不用,适用于快速开发,
4.使用工厂方式创建Bean
实例工厂和静态工厂两种方式可以实现
5.Lifecycle Customization(组件的生命周期)
模版方法
回调
Thread t = new MyThread()
t.start()
回调加模版方法
实现了InitializingBean接口
或者通过init-method指定方法,允许容器在设置
好bean的所有必要属性后,调用接口方法或指定
方法进行初始化工作:同样,实现DisposableBean或者
通过destroy-method指定方法,允许在容器销毁该bean的时候
获得一次回调
Spring容器管理Bean一般过程:
step1:先实例化Bean(必须的)
step2:装配(可选的)
step3:回调方法(可选的包含了获取资源的方法[有很多])
step4:就绪(可以被调用)
step5:销毁(销毁之前如果有回调方法[释放资源]则执行)
ApplicationContext容器提供的接口
ApplicationContextAware接口
setApplicationContext()
要求:
Person p1 = new Person();
Car c1 = p1.getCar();
Person p2 = new Person();
Car c2 = p2.getCar();
初始化方法 回调接口

Thread
start()
run()
MyThread
run()
先申请资源
释放资源
回调类
控制类
Web容器
Servlet
Person
getCar() Car
Scope="singlton"
Scope="prototype"
car
Can define init method called after peoperties set
最后采用配置文件的方式或者标注的方式回调,最好不要使用接口回调
BeanPostProcessors(拦截器)
实现了BeanPostProcessors接口的Bean,称之为"后处理Bean"(扩展容器功能)
Bean已经实例化之后,实施"加工"
1.实例化 2.装配 3.回调(初始化)
step2:使用BFP修改已加载的配置
BeanPostProcesser
step1:加载
BeanFactoryPostProcessor当加载的类文件之后,实例化Bean之前,一般用来修改Bean
的配置
如果要在Spring容器完成bean的实例化,配置和其它的初始化后执行一些子定义逻辑,
可以加入一个或多个BeanPostProcessor实现.
6.Spring的事件处理(观察者模式)
java中
事件处理的好处:
1.可以实现一对多的
通信或调用
2.系统的耦合性低
编程的方式:做三件事情
step1:自定义事件 ApplicationEvent


Spring
的类
文件
容器
接口
监听器
按钮
事件
Spring容器
CustomerService
register()
CustomerListener
处理注册事件
1 先通过配置文件注册
2发布事件
事件
3抛给Listener
step2:开发监听器(必须实现Application Listener接口)
step3:要发布事件的Bean(组件)要实现ApplicationContextAware接口
再调用容器去发布事件
分享到:
评论

相关推荐

    Spring中IoC优点与缺点解析

    Spring 中 IoC 优点与缺点解析 IoC(Inversion of Control)是 Spring 框架中的一种设计模式,它的主要思想是将对象的创建和管理交给容器,从而解耦合对象之间的依赖关系。今天,我们将详细解析 IoC 的优点和缺点。 ...

    自己实现ioc实例demo

    在IT行业中,依赖注入(IOC,Inversion of Control)是一种设计模式,它使得应用程序的组件之间解耦,提高了代码的可测试性和可维护性。在这个“自己实现ioc实例demo”中,我们将探讨如何通过XPath解析XML文件来实现...

    雷赛IOC0640.rar

    标题中的“雷赛IOC0640.rar”指的是雷赛智能公司的一款名为IOC0640的工业控制产品,该产品通常用于自动化控制系统中,提供高效、稳定的输入/输出(I/O)管理。这个压缩包可能包含了关于该产品的详细资料和技术文档。...

    IoC容器的设计(利用反射、注解和工厂模式实现)

    2. 该IoC容器包含3个注解和一个IoC容器类(AnnotationConfigApplicationContext),其定义如下: 注解 含义 @Component 标注Bean @Autowired 标注需要被注入的对象 @Configuration 标注为配置类 @ComponentScan ...

    springIoc实现原理

    **Spring Ioc 实现原理详解** Spring Ioc(Inversion of Control,控制反转)是Spring框架的核心特性之一,它改变了传统应用程序中对象的创建和管理方式。在传统的软件设计中,对象的创建和依赖关系的维护通常由...

    spring Ioc容器配置

    spring Ioc容器配置 IOC容器数据源配置 &lt;!-- 配置数据源 --&gt; destroy-method="close"&gt; &lt;value&gt;org.gjt.mm.mysql.Driver &lt;value&gt;jdbc:mysql://localhost:3306/demo &lt;value&gt;root ...

    雷泰IOC-0640控制卡用户手册V1.3

    根据给定的文件信息,以下是对雷泰IOC-0640控制卡用户手册V1.3中的关键知识点的详细解读: ### 关于本手册 本手册是针对雷泰IOC-0640控制卡的详细用户指南,旨在帮助用户了解如何使用这款设备。手册分为七个章节,...

    Spring的IoC实现案例

    在本文中,我们将深入探讨如何使用Spring的Inversion of Control(IoC)容器来实现一个具体的案例:控制打印机(Printer)类与不同类型的纸张(Paper)类的交互。Spring的IoC允许我们解耦组件,使代码更加灵活且易于...

    以注解方式模拟Spring IoC AOP

    在Spring框架中,依赖注入(Inversion of Control, IoC)和面向切面编程(Aspect Oriented Programming, AOP)是两大核心特性。本篇将深入探讨如何通过注解方式来模拟Spring的这两种机制,帮助你理解其底层原理。 #...

    C#实现的IOC和AOP框架,供学习

    在现代软件开发中,依赖注入(IOC,Inversion of Control)和面向切面编程(AOP,Aspect-Oriented Programming)是两种非常重要的设计模式,它们有助于提高代码的可测试性、可维护性和模块化程度。这个名为...

    图片转IOC图标工具

    "图片转IOC图标工具"正是一款专为开发者设计的实用工具,旨在帮助他们将普通的图片转换为适用于iOS平台的.IOC图标格式。 .IOC(Image Asset Catalog)是苹果iOS开发中的图像资源格式,主要用于存储不同尺寸和状态的...

    IOC835芯片 MM-PIO835-1P驱动程序 解压密码:hebeiww

    PCI并口卡 PCI转打印并口DB25接口扩展卡 IOC835芯片驱动 功能描述: 在具备PCI插槽的电脑上扩展出1个DB25并口 规格说明: 符合PCIRev2.1协议 传输率最大可达1.5 Mbytes/sec 1个DB25并口接头 符合标准的带16byte接收...

    一个简单的模仿spring的ioc实现

    在IT行业中,Spring框架是Java开发中的重要组成部分,特别是其依赖注入(Dependency Injection,简称DI)功能,也称为控制反转(Inversion of Control,IoC)。这个“一个简单的模仿spring的ioc实现”项目旨在帮助...

    雷赛IOC0640函数库.rar

    "雷赛IOC0640函数库.rar" 是一个压缩包,其中包含了针对雷赛(LeiSee)IOC0640设备的编程接口。这个函数库主要用于与该设备进行通信和控制,支持C++、C#以及VB(Visual Basic)三种编程语言,通过动态链接库(DLL)...

    IOC模式 c#经典例子

    IOC(Inversion of Control,控制反转)模式是一种软件设计原则,它在面向对象编程中用于解耦组件之间的依赖关系。C#中实现IOC的一种常见方式是通过依赖注入(Dependency Injection,DI)。在这个“IOC模式 c#经典...

    什么是Ioc和DI

    ### 什么是控制反转(IoC)与依赖注入(DI) #### 控制反转(IoC) 控制反转(Inversion of Control,简称IoC)是软件工程领域的一个设计模式,主要用于简化对象之间的依赖关系管理。在传统的面向对象编程中,对象间的...

    spring ioc和aop原理流程图(详细)

    Spring 框架是Java开发中的核心框架,它主要由两个关键部分组成:IOC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)。这两个概念是Spring框架的核心特性,极大地简化了企业...

    SpringIoC的简单实现

    我们从一个简单的容器开始,一步步的重构,最后实现一个基本的Spring框架的雏形,为了帮助我们更加深入的理解Spring的IoC的原理和源码。 详细内容见博文: 【SSH进阶之路】一步步重构容器实现Spring的IoC——从一个...

    JavaEE Spring IoC入门

    JavaEE Spring IoC(Inversion of Control,控制反转)是企业级应用开发的重要技术,它极大地简化了Java应用程序的构建和维护。Spring框架的核心特性就是IoC,它通过管理对象的生命周期和对象间的依赖关系,使得...

    IoC 依赖注入 技术总结

    "IoC 依赖注入 技术总结" IoC 依赖注入技术是软件设计中的一种重要技术,旨在解决软件系统中的耦合问题。该技术的核心思想是将被调用构件实例化,并注入到调用构件之中,以实现软件系统的高内聚、低耦合。IoC 依赖...

Global site tag (gtag.js) - Google Analytics