Spring----模拟Spring容器创建bean

目录结构

在这里插入图片描述

  • 自定义工厂模拟spring容器,实例化类对象
	public interface AccountDao {
	    public void saveAcount();
	}
	public class AccountDaoImpl implements AccountDao {
	    @Override
	    public void saveAcount() {
	        out.println("AccountDaoImpl.java--saveAcount--12-->"+ "请求成功");
	    }
	}
	public interface AccountService {
	    public void saveAccount();
	}
	public class AccountServiceImpl implements AccountService {
	    private AccountDaoImpl dao= (AccountDaoImpl) BeanFactory.getBean("accountDaoImpl");
	    @Override
	    public void saveAccount() {
	        dao.saveAcount();
	        out.printf("AccountServiceImpl.java--saveAccount--10--> ","保存成功");
	    }
	}
	
	/**
	 * @ Author: WangGQ
	 * @ Date: 2019/12/26 20:37
	 * @ Version: 1.0
	 * @ Description: 创建对象工厂
	 */
	public class BeanFactory {
	    public static Properties pros;
	    public static Map<String,Object> beans;
	    static {
	        try {
	            pros = new Properties();
	            InputStream in = BeanFactory.class.getClassLoader().getResourceAsStream("beans.properties");
	            pros.load(in);
	            //----改造----start---
	            Enumeration enums=pros.keys();
	            beans=new HashMap<String,Object>();         //实例化容器
	            while (enums.hasMoreElements()){
	                try {
	                    String key    = (String) enums.nextElement();
	                    String keyPath=pros.getProperty(key);
	                    Object obj=Class.forName(keyPath).newInstance();
	                    beans.put(key,obj);
	                }catch (Exception e){
	                    e.printStackTrace();
	                }
	            }
	            //----改造----end---
	        } catch (IOException e) {
	            throw new ExceptionInInitializerError("读取配置文件失败");
	        }
	    }
	     /**
	      * @ Author: WangGQ
	      * @ Date: 2019/12/26 21:04
	      * @ Version: 1.0
	      * @ Description: 获取bean,Class.forName(beanPath).newInstance()调用的是类的默认的构造方法,所以创建的bean是多例的
	      */
	    public static Object getBean(String beanName){
	        Object obj = null;
	            try{
	                String beanPath=pros.getProperty(beanName);
	                obj=Class.forName(beanPath).newInstance();
	            }catch (Exception e){
	                    e.printStackTrace();
	            }
	        return obj;
	    }
	    public static Object createBean(String beanName){
	        return beans.get(beanName);
	    }
	}
	public class test1 {
	    public static void main(String[] args) {
	//        AccountServiceImpl service= (AccountServiceImpl) BeanFactory.getBean("accountServiceImpl");
	        AccountServiceImpl service= (AccountServiceImpl) BeanFactory.createBean("accountServiceImpl");
	        service.saveAccount();
	    }
	}
	//运行结果
	AccountDaoImpl.java--saveAcount--12-->请求成功
	AccountServiceImpl.java--saveAccount--10--> 
	Process finished with exit code 0
  • beans.properties
accountDaoImpl=com.gsau.dao.impl.AccountDaoImpl
accountServiceImpl=com.gsau.service.impl.AccountServiceImpl
使用spring ApplicationContext获取实例化类对象
	package com.gsau.factory;
	import org.springframework.context.ApplicationContext;
	import org.springframework.context.support.ClassPathXmlApplicationContext; 
	/**
	 * @ Description:  使用spring容器获取bean实例
	 * @ Date: 2019/12/27 9:57
	 * @ Author: wgq
	 * @ Version: 1.0
	 */
	public class SpringBeanFactory {
	    public static ApplicationContext ioc=null;
	     /**
	      * @ Description:  初始初始化Spring容器
	      * @ Date: 2019/12/27 10:22
	      * @ Author: wgq
	      * @ Version: 1.0
	      */
	    static {
	        ioc= new ClassPathXmlApplicationContext("SpringBeans.xml");
	    }
	     /**
	      * @ Description:  取容器中组件 
	      * @ Date: 2019/12/27 10:22
	      * @ Author: wgq
	      * @ Version: 1.0
	      */
	    public static Object getBean(String beanName){
	       return  ioc.getBean(beanName);
	    }
	    public static  < obj > obj getBean(String beanName,Class<obj> obj){
	        return  ioc.getBean(beanName,obj);
	    }
	}
  • ApplicationContext 接口继承关系
    在这里插入图片描述

  • ApplicationContext 接口实现关系 在这里插入图片描述

  • ApplicationContext 接口的实现类功能

    • .ClassPathXmlApplicationContext: 它是从类的根路径下加载配置文件 推荐使用这种
    • . FileSystemXmlApplicationContext: 它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。
    • . AnnotationConfigApplicationContext: 当我们使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解
  • BeanFactory 和 ApplicationContext 的区别

    • 1. BeanFactory 才是 Spring 容器中的顶层接口,ApplicationContext 是它的子接口
    • 2. BeanFactory 和 ApplicationContext 的区别:创建对象的时间点不一样
    • 3. ApplicationContext:只要一读取配置文件,默认情况下就会创建对象。
    • 4. BeanFactory:什么使用什么时候创建对象。
  • Spring 实例化 Bean 的三种方式
    1. 使用默认无参构造函数
    2.Spring 管理工厂-使用工厂的静态方法创建对象
    3.spring 管理实例工厂-使用实例工厂的方法创建对象

     <!--在默认情况下:它会根据默认无参构造函数来创建类对象。如果 bean 中没有默认无参构造函数,将会创建失败。-->
    <bean id="person" class="com.gsau.entity.Person"></bean>
    <!--此种方式是::spring 管理静态工厂-使用静态工厂的方法创建对象
         使用 SpringBeanFactory 类中的静态方法 instanceBean 创建对象,并存入 spring 容器
         id 属性:指定 bean 的 id,用于从容器中获取
         class 属性:指定静态工厂的全限定类名
         factory-method 属性:指定生产对象的静态方法-->
    <bean id="emp" class="com.gsau.factory.SpringBeanFactory" factory-method="instanceBean"></bean>
    <!-- 此种方式是: spring 管理实例工厂-使用实例工厂的方法创建对象
            先把工厂的创建交给 spring 来管理。
            然后在使用工厂的 bean 来调用里面的方法
            factory-bean 属性:用于指定实例工厂 bean 的 id。
            factory-method 属性:用于指定实例工厂中创建对象的方法。
    -->
    <bean id="springBeanFactory" class="com.gsau.factory.SpringBeanFactory"></bean>
    <bean id="dept" factory-bean="springBeanFactory" factory-method="createBean"></bean>
    
    	import com.gsau.entity.Dept;
    	import com.gsau.entity.Emp;
    	import org.springframework.context.ApplicationContext;
    	import org.springframework.context.support.ClassPathXmlApplicationContext;
    	/**
    	 * @ Description:  使用spring容器获取bean实例
    	 * @ Date: 2019/12/27 9:57
    	 * @ Author: wgq
    	 * @ Version: 1.0
    	 */
    	public class SpringBeanFactory {
    	    public static ApplicationContext ioc=null;
    	     /**
    	      * @ Description:  初始初始化Spring容器
    	      * @ Date: 2019/12/27 10:22
    	      * @ Author: wgq
    	      * @ Version: 1.0
    	      */
    	    static {
    	        ioc= new ClassPathXmlApplicationContext("SpringBeans.xml");
    	    }
    	     /**
    	      * @ Description:  取容器中组件 
    	      * @ Date: 2019/12/27 10:22
    	      * @ Author: wgq
    	      * @ Version: 1.0
    	      */
    	    public static Object getBean(String beanName){
    	       return  ioc.getBean(beanName);
    	    }
    	    public static  < obj > obj getBean(String beanName,Class<obj> obj){
    	        return  ioc.getBean(beanName,obj);
    	    }
    	     /**
    	      * @ Description:   用于测试bean创建的三种方式:使用自定义工厂类
    	      * @ Date: 2019/12/27 13:52
    	      * @ Author: wgq
    	      * @ Version: 1.0
    	      */
    	    public static Object instanceBean(){
    	        return new Emp();
    	    }
    	     /**
    	      * @ Description:  用于测试bean创建的三种方式: 使用实例工厂的方法创建对象
    	      * @ Date: 2019/12/27 14:14
    	      * @ Author: wgq
    	      * @ Version: 1.0
    	      */
    	    public  Object createBean(){
    	        return new Dept();
    	    }
    	}
    	//测试类
    	public class test1 {
        public static void main(String[] args) {
    //        AccountServiceImpl service= (AccountServiceImpl) BeanFactory.getBean("accountServiceImpl");
            AccountServiceImpl service= SpringBeanFactory.getBean("accountServiceImpl",AccountServiceImpl.class);
            Person person=SpringBeanFactory.getBean("person", Person.class);
            Emp emp=SpringBeanFactory.getBean("emp", Emp.class);
            Dept dept=SpringBeanFactory.getBean("dept", Dept.class);
    
            System.out.println("test1-test1-13->"+person.toString());
            System.out.println("test1-test1-17->"+emp.id);
            System.out.println("test1-test1-20->"+dept.name);
            service.saveAccount();
        }
    }
    
  • Spring IOC 中 bean 标签和管理对象细节

    • bean 标签
      • 作用:
          用于配置对象让 spring 来创建的,默认情况下它调用的是类中的无参构造函数。如果没有无参构造函数则不能创建成功
      • 属性:
        id:给对象在容器中提供一个唯一标识。用于获取对象。
        class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。
        scope:指定对象的作用范围。
           singleton :默认值,单例的.
           prototype :多例的.
           request :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 request 域中.
           session :WEB 项目中,Spring 创建一个 Bean 的对象,将对象存入到 session 域中.
           global session :WEB 项目中,应用在 Portlet 环境.如果没有 Portlet 环境那么 globalSession 相当于 session.
           init-method:指定类中的初始化方法名称。
           destroy-method:指定类中销毁方法名称。
    • bean 的作用范围和生命周期
      • 单例对象:scope=“singleton”:
           每次访问对象时,都会重新创建对象实例
        生命周期:
           1. 对象出生:当应用加载,创建容器时,对象就被创建了。
           2. 对象活着:只要容器在,对象一直活着。
            3. 对象死亡:当应用卸载,销毁容器时,对象就被销毁了。
      • 多例对象 :scope=“prototype”:
           一个应用只有一个对象的实例。它的作用范围就是整个引用
          person 生命周期:
           1. 对象出生:当使用对象时,创建新的对象实例。
           2. 对象活着:只要对象在使用中,就一直活着。
           3. 对象死亡:当对象长时间不用时,被 java 的垃圾回收器回收了
  • spring 的依赖注入
      依赖注入: Dependency Injection。它是 spring 框架核心 ioc 的具体实现。我们的程序在编写时,通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。 ioc 解耦只是降低他们的依赖关系,但不会消除。例如:我们的业务层仍会调用持久层的方法。那这种业务层和持久层的依赖关系,在使用 spring 之后,就让 spring 来维护了。
       简单的说: 就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。

    • 能注入的对象
      • 能注入的数据有:
        • 1.基本数据类型和String
        • 2.其他的bean类型(在配置文件或者注解中配置过的本)
        • 3.复杂类型/map类型
      • 注入的方式:
        • 1.使用构造函数
        • 2.使用set方法操作
        • 3.使用注解提供
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值