Spring深入浅出(二)IOC详解
来源:互联网 发布:域名买卖网 编辑:程序博客网 时间:2024/06/06 12:52
IOC即inverse of control 控制反转
以前对象之间的引用是通过new来调用实现,有了Spring IOC,我们可以把对象之间的引用交给他来管理,这样就把控制权交给了Spring,所以就叫做控制反转。
Spring IOC的实现用到了设计模式:简单工厂,他也是从简单工厂进化而来的,下面我们看看Spring的IOC是如何进化来的。
简单工厂模式实现:- <span style="font-weight: normal;">package org;
- //抽象接口
- interface Fruit{
- public void eat();
- }
- //实现类A
- class Apple implements Fruit{
- public void eat(){
- System.out.println("吃苹果。");
- }
- }
- //实现类B
- class Orange implements Fruit{
- public void eat(){
- System.out.println("吃橘子");
- }
- }
- //工厂类
- class Factory{
- public static Fruit getInstance(String className){
- Fruit f=null;
- if(className.equals("apple")){
- f=new Apple();
- }
- if(className.endsWith("orange")){
- f=new Orange();
- }
- return f;
- }
- }
- public class FactoryDemo02 {
- public static void main(String args[]){
- Fruit f=Factory.getInstance("apple");
- f.eat();
- }
- }</span>
- <span style="font-weight: normal;">package org;
- //抽象接口
- interface Fruit{
- public void eat();
- }
- //实现类A
- class Apple implements Fruit{
- public void eat(){
- System.out.println("吃苹果。");
- }
- }
- //实现类B
- class Orange implements Fruit{
- public void eat(){
- System.out.println("吃橘子");
- }
- }
- //工厂类
- class Factory{
- public static Fruit getInstance(String className){
- Fruit f=null;
- if(className.equals("apple")){
- f=new Apple();
- }
- if(className.endsWith("orange")){
- f=new Orange();
- }
- return f;
- }
- }
- public class FactoryDemo02 {
- public static void main(String args[]){
- Fruit f=Factory.getInstance("apple");
- f.eat();
- }
- }</span>
反射+简单工厂
但是工厂类如果这样写的话,就有一个问题,如果增加了水果,比如香蕉,那么在工厂类里面也要进行相关的修改了,这样不合理,而java的反射机制可以解决这个问题- package org1;
- interface Fruit {
- public void eat();
- }
- class Apple implements Fruit {
- public void eat() {
- System.out.println("吃苹果。");
- }
- }
- class Orange implements Fruit {
- public void eat() {
- System.out.println("吃橘子");
- }
- }
- class Factory {
- public static Fruit getInstance(String className) {
- Fruit f = null;
- try {
- f = (Fruit) Class.forName(className).newInstance();
- } catch (Exception e) {
- e.printStackTrace();
- }
- return f;
- }
- }
- public class CopyOfFactoryDemo03 {
- public static void main(String args[]) {
- Fruit f = Factory.getInstance("org1.Apple");
- f.eat();
- }
- }
反射+简单工厂+xml配置文件
利用java的反射机制,就能动态的实例化各种类了。 但是这个程序还是存在一个问题,就是主函数这里需要填入一个完整的类名称,不够方便,所以要增加配置文件来简化- package org3;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.util.Properties;
- interface Fruit {
- public void eat();
- }
- class Apple implements Fruit {
- public void eat() {
- System.out.println("吃苹果。");
- }
- }
- class Orange implements Fruit {
- public void eat() {
- System.out.println("吃橘子");
- }
- }
- class Factory {
- public static Fruit getInstance(String className) {
- Fruit f = null;
- try {
- f = (Fruit) Class.forName(className).newInstance();
- } catch (Exception e) {
- e.printStackTrace();
- }
- return f;
- }
- }
- class PropertiesOperate{
- private Properties pro=null;
- private File file=new File("d:"+File.separator+"fruit.properties");
- public PropertiesOperate(){
- this.pro=new Properties();
- if(file.exists()){
- try {
- pro.loadFromXML(new FileInputStream(file));
- } catch (Exception e) {
- e.printStackTrace();
- }
- }else{
- this.save();
- }
- }
- private void save(){
- this.pro.setProperty("apple","org3.Apple");
- this.pro.setProperty("orange", "org3.Orange");
- try {
- this.pro.storeToXML(new FileOutputStream(this.file),"Fruit");
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- public Properties getProperties(){
- return this.pro;
- }
- }
- public class CopyOfFactoryDemo04 {
- public static void main(String args[]) {
- Properties pro=new PropertiesOperate().getProperties();
- Fruit f= Factory.getInstance(pro.getProperty("apple"));
- f.eat();
- }
- }
终极版本Spring IOC
加入配置文件问题就解决了,以后如果要增加新的水果类,都要在这个配置文件里面登记。这时我们可以说配置文件可以控制程序的执行,现在看起来有点像spring的ioc了。下面我们来看看Spring IOC是如何实现的。- package test2;
- public class Person {
- private String name;
- private int age;
- private Grade grade;
- public String getName() {
- return name;
- }
- public Grade getGrade() {
- return grade;
- }
- public void setGrade(Grade grade) {
- this.grade = grade;
- }
- public void setName(String name) {
- this.name = name;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public int getAge() {
- return age;
- }
- public int getTotleGrade() {
- return grade.getEnglish()+grade.getMath();
- }
- }
- package test2;
- public class Grade {
- private int math;
- private int english;
- public int getMath() {
- return math;
- }
- public void setMath(int math) {
- this.math = math;
- }
- public int getEnglish() {
- return english;
- }
- public void setEnglish(int english) {
- this.english = english;
- }
- }
Bean.xml配置文件(该文件只要放在test2包里面就好了)
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
- "http://www.springframework.org/dtd/spring-beans.dtd">
- <beans>//很多豆豆
- <bean id="Person" class="test2.Person">//第一个豆豆,是一个Person类,id名字随便取,还要写上类的全名
- <property name="name">//下面开始把这个类里面的所有属性列出来,并赋值,至于你说难道一定要赋值吗?我想可以,我刚学,不知道
- <value>小龙</value>//这里的名字是通过程序里面的set来赋值的,不信你去掉程序里面相关的set,就出错了
- </property>
- <property name="age">
- <value>23</value>
- </property>
- <property name="grade">//这里有点特别,这个grade变量是一个对象,和一般的变量要区别对待
- <ref local="Grade"/>//这里指向了本配置文件里面一个名字叫Grade(即id=Grade)的bean
- </property>
- </bean>
- <bean id="Grade" class="test2.Grade">//同上
- <property name="math">
- <value>99</value>
- </property>
- <property name="english">
- <value>59</value>
- </property>
- </bean>
- </beans>
Test类
- package test2;
- import org.springframework.beans.factory.BeanFactory;
- import org.springframework.beans.factory.xml.XmlBeanFactory;
- import org.springframework.core.io.ClassPathResource;
- import org.springframework.core.io.Resource;
- import test.ExampleBean;
- public class Test {
- public static void main(String args[]){
- Resource input = new ClassPathResource("test2/Bean.xml");//Bean.xml的路径
- System.out.println("resource is:" + input);
- BeanFactory factory = new XmlBeanFactory(input);//把input扔到工厂里面去,这个工厂就能为你提供实例了(我也不知道能不能这样说)
- Person person =(Person) factory.getBean("Person");//你要一个叫Person的东西,那好,工厂就去找“Person"给你
- Grade grade=(Grade)factory.getBean("Grade");
- System.out.println("姓名:"+person.getName());//person可以调用里面相关的方法,就相当于new了一个Person一样
- System.out.println("年龄:"+person.getAge());
- System.out.println("数学成绩:"+grade.getMath());
- System.out.println("英语成绩:"+grade.getEnglish());
- System.out.println("数学,英语总成绩:"+person.getTotleGrade());
- }
- }
如此看来,你在对比一开始的那个水果的程序,你会发现,spring配置文件,还是一个工厂,只不过换种形式一样,他管理所有的类,新建的类要到工厂里面去登记,不然就不能被主程序用,这就是为什么说ioc就是工厂模式的升级版。至于配置文件的书写,就跟堆积木一样。
---------------------------------
顺便提下,关于Spring读取配置文件的方法:
applicationcontext---
FileSystemXmlApplicationContext---这个方法是从文件绝对路径加载配置文
ClassPathXmlApplicationContext---这个方法是从classpath下加载配置文件(适合于相对路径方式加载)
XmlWebApplicationContext----专为web工程定制的方法,推荐Web项目中使用。
beanfactory---
ClassPathResource --- 从系统的类路径中加载
FileSystemResource --- 从文件系统加载,比如说自己指定配置文件的全路径
InputStreamResource --- 从输入流中加载
ServletContextResource --- 从Servlet 上下文环境中加载
UrlResource --- 从指定的Url加载
FileSystemResource --- 从文件系统加载,比如说自己指定配置文件的全路径
InputStreamResource --- 从输入流中加载
ServletContextResource --- 从Servlet 上下文环境中加载
UrlResource --- 从指定的Url加载
---------------------------------------------
BeanFactory和ApplicationContext的区别
ApplicationContext接口,它由BeanFactory接口派生而来,因而提供BeanFactory所有的功能。ApplicationContext以一种更向面向框架的方式工作以及对上下文进行分层和实现继承,ApplicationContext包还提供了以下的功能:
• MessageSource, 提供国际化的消息访问
• 资源访问,如URL和文件
• 事件传播
• 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层
• MessageSource, 提供国际化的消息访问
• 资源访问,如URL和文件
• 事件传播
• 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层
最主要的就是BeanFactory延迟加载,当使用到getBean的时候才会抛异常,而ApplicationContext在刚开始启动加载的时候就会抛出异常,这样有利于检查所依赖属性是否注入;所以通常情况下我们选择使用ApplicationContext。
0 0
- Spring深入浅出(二)IOC详解
- Spring深入浅出(二)IOC详解
- Spring深入浅出(二)IOC详解
- 深入浅出Spring(二) IoC详解
- 深入浅出Spring(二) IoC详解
- Spring深入浅出IOC详解
- spring之IOC详解二
- Spring之IOC和DI深入浅出的详解
- (二)Spring详解——Ioc
- Spring学习笔记(二)IOC详解
- Spring详解(二)------IOC控制反转
- 深入浅出Spring(二) AOP详解
- 深入浅出spring IOC 依赖注入
- 深入浅出~spring IOC和DI
- Spring Ioc学习(二)
- Spring—IoC(二)
- Spring(二) IoC
- Spring IOC(二)
- pandas+xlrd操作excel批量读写全体sheet
- ./configure,make,make install的作用
- Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之间的关系
- storm ui显示supervisor个数与实际不符的解决
- Transferring Data Without Draining the Battery - Optimizing Downloads for Efficient Network Access
- Spring深入浅出(二)IOC详解
- Apache配置详解(最好的APACHE配置教程)
- notepad的技巧性问题
- 软件测试工具
- Maven原理和Maven2新特性
- mac 上python简易爬虫
- 你的能量超乎想象-记2014.9-2015.2
- libxl库的使用
- 干支纪年,2015为什么是乙未年?