3.实例化工厂和依赖创建对象

1.看图

3.实例化工厂和依赖创建对象

2.业务层接口IAccountService

package com.itheima.service;

public interface IAccountService {

    void saveAccount();

}

3.业务实现类 IAccountServiceImp

package com.itheima.service.lmp;

import com.itheima.service.IAccountService;

public class IAccountServiceImp implements IAccountService {
//业务层调用——持久层——调用控制层
    //默认构造函数
    //public IAccountServiceImp(String name)写了参数就不是默认构造函数了
    //这个是一个默认构造函数
    public IAccountServiceImp(){
        System.out.println("对象被创建了");
    }
    public void saveAccount() {
       System.out.println("service中的saveAccount被执行了......");

    }
}

4.这里其实先去bean文件创建对象(但是放后面也可以)

4-1.InstanceFactory用的是返回值对象来创建对象,那就在bean中只能用其他属性来获取

package com.itheima.factory;

import com.itheima.service.IAccountService;
import com.itheima.service.lmp.IAccountServiceImp;

/*
* 模拟一个工厂类(该类可能是存在于jar包中的,我们无法通过修改源码的方式来提供默认函数)
* */
public class InstanceFactory {

    public IAccountService getAccountService(){
// 用的是返回值对象来创建对象,那就在bean中只能用其他属性来获取
        return  new IAccountServiceImp();
    }
}

 5.和上面的一样(作用不一样)staticFactory静态工厂(用于实例化的方法创建对象)

package com.itheima.factory;

import com.itheima.service.IAccountService;
import com.itheima.service.lmp.IAccountServiceImp;

/*
* 模拟一个工厂类(该类可能是存在于jar包中的,我们无法通过修改源码的方式来提供默认函数)
* */
public class staticFactory {
//静态的的方法(static只能在该模块中使用,有局限性)
    public static IAccountService getAccountService(){
// 用的是返回值对象来创建对象,那就在bean中只能用其他属性来获取
        return  new IAccountServiceImp();
    }
}

6.依赖spring容器的

<dependencies>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.2.RELEASE</version>
  </dependency>
</dependencies>

7.bean.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">
<!--    id:对象名(也是唯一标识)class:全限定类名-->
<!--    传入的是每个层的实现类,因为使用实现类才能创建实例对象-->
<!--    <bean id="accountService" class="com.itheima.service.lmp.IAccountServiceImp"></bean>-->

<!--把对象的创建交给spring来管理-->
<!--spring对bean的管理细节
     1. 创建bean的三种方式
     2. bean对象的作用范围
     3. bean对象的生命周期
-->
<!--1.创建对象的的三种方式-->
<!-- 第一种方式:使用默认构造函数的创建
         在spring的配置文件中使用bean标签,配以id和class属性之后,且没有其他属性和标签时。
         采用的就是默认构造函数创建bean对象,此时如果类(实现类)中没有默认构造函数,则对象无法创建(默认构造函数传参了也无法创建bean对象)。
-->
<!-- 第二种方式:使用普通工厂中的方法来创建对象(使某个类中的方法创建对象,并存入spring容器)-->
<!--
理由:方法模块具有块级作用域所以必有特定的方法来取(域在方法中)
    <bean id="instanceFactory" class="com.itheima.factory.InstanceFactory"></bean>
    <bean id="accountService" factory-bean="instanceFactory" factory-method="getAccountService"></bean>-->

<!-- 第三种方法:使用工厂中的静态方法创建对象(或者使用某个类中的静态方法创建对象,并存入spring容器)-->
<!--    成了静态方法:getAccountService"-->
<!--    理由:方法模块是静态的static 具有块级作用域所以必有特定的方法来取(域在静态方法中)-->
<!--    <bean id="instanceFactory" class="com.itheima.factory.staticFactory" factory-method="getAccountService"></bean>-->

<!--第二第三都是根据:不可变的,如果在jar包中的类的话,那就直接使用二或者三-->

    <bean id="accountService" class="com.itheima.service.lmp.IAccountServiceImp"></bean>
<!--
        bean的作用范围的调整
            bean的标签scope属性:
                作用:
                取值:(常用单例和多例)
                    singleton:单例的(默认值)
                    prototype:多例的
                    request:作用于web应用的请求范围
                    session:作用于web应用的会话范围
                    global-session:作用于在集群环境的会话范围(全局会话范围),
                                    当不是集群环境的时候,他就是session
            2. 生命周期:
                bean对象
                 单例对象
                    出生:当容器创建的时候对象出生
                    活着:当容器还在的时候,对象一直在(立即机制)
                    死亡:当容器销毁,对象死亡
                    总结:单例对象和容器的生命周期相同
                 多例对象
                    出生:当我们使用对象时spring框架为我们创建
                    活着:对象只要在使用,就会一直存在(延迟机制)
                    死亡: 当对象长期不用,且没有别的对象引用时,由java的垃圾回收器回收


-->



</beans>

8.Client表现层-调用业务

package com.itheima.ui;


import com.itheima.service.IAccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


//模拟一个表现层,用于调用业务层
public class Client {
    /*
    * 获取spring的Ioc核心容器,并且根据id获取对象
    */
    public static void main(String[] args) {
        //1.获取核心容器对象(获取bean容器)ac 不管你取什么名都可以,然后使用这个ac去找到bean对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        //2.根据id获取bean对象(这里为什么要用IAccountService,那是遵循三层架构思想[])
        IAccountService as = (IAccountService) ac.getBean("accountService");
        //System.out.println("as="+as);
        as.saveAccount();
    }
    /*
    *dao: Client调用IAccountServiceImp调用IAccountDaoImp(创建实例化对象的时候)
    * service:业务返回:IAccountDao ——>IAccountService——>显示Client
    */
    /*IAccountService as = new IAccountServiceImp();普通用法:独立就用spring容器*/
}

9.两个工厂需要区分:bean.xml写,都是用反射机制来创建对象,作用不同而已