01_Spring【IOC+依赖注入】

工厂模式

工厂模式概述:

工厂模式是一种常见的设计模式。是一种通过工厂方法,代替new操作,帮助我们创建对象的设计模式。

工厂模式解耦基础版本

编写工厂类四个基本步骤

-第一步:
声明一个私有的工厂类对象引用
-第二步:
把构造方法私有化
-第三步:
通过静态代码块初始化
-第四步:
提供一个公有的、静态的方法,获取工厂类对象引用

工厂模式解耦改良
改良思路:
1.通过配置文件,将要创建的目标对象的类型信息,进行配置
2.在工厂类中加载配置文件,通过反射技术实现运行时加载,并创建目标对象

工厂模式解耦理解

在实际项目开发中,我们可以通过配置文件把service、dao对象配置起来,当启动服务器加载应用的时候,读取配置文件,创建配置文件中的对象并且保存起来。在接下来实际使用的地方,直接拿过来使用即可。此时我们需要考虑两个问题:

问题一:将对象存放在什么地方?

由于在一个应用中,会需要大量的对象,首先考虑把对象存储到什么地方。在java中有对应的集合List和Map。选择什么好呢?考虑到我们有查找的需求,那么选择Map比较好。

问题二:什么是工厂呢?

工厂就是负责创建对象,并且把对象放到容器中。在实际使用的时候,帮助我们从容器获取指定的对象。此时我们获取对象的方式发生了改变。
tips:原来我们获取对象时,都是采用new的方式。是主动获取.
现在我们获取对象时,找工厂要,由工厂创建并且提供给我们。是被动接收

结论:

这种获取对象方式的转变(由原来主动获取,到现在被动接收),我们称它为控制反转。控制反转,即IOC(Inversion Of Control)。

IOC,其实它就是我们刚才的工厂模式解耦。

原来获取对象的方式:


01_Spring【IOC+依赖注入】_第1张图片
image.png

现在获取对象的方式:


01_Spring【IOC+依赖注入】_第2张图片
image.png

Spring

概述

spring框架是J2EE企业级应用的轻量级开源框架。它是以IOC(Inversion Of Control)控制反转、和AOP(Aspect Oriented Programming)面向切面编程为核心;提供了表现层springmvc和持久层spring JDBC,以及业务层的事务管理等企业级应用解决方案;还能实现将开源世界中众多优秀的第三方框架整合,成为越来越受欢迎的J2EE企业级应用框架。

spring框架发展历程
  • 1997年IBM提出了EJB的思想

  • 1998年,SUN制定开发标准规范EJB1.0

  • 1999年,EJB1.1发布

  • 2001年,EJB2.0发布

  • 2003年,EJB2.1发布

  • 2006年,EJB3.0发布

  • Rod Johnson(spring之父)

Expert One-to-One J2EE Design and Development(2002)
阐述了J2EE 使用EJB 开发设计的优点及解决方案

Expert One-to-One J2EE Development without EJB(2004)

阐述了J2EE 开发不使用EJB 的解决方式(Spring 雏形)

  • 2017 年9 月份发布了spring 的最新版本spring 5.0 通用版(GA)


    01_Spring【IOC+依赖注入】_第3张图片
    image.png

Spring框架优点

IOC解耦,简化开发

通过spring提供的IOC容器,可以将对象间的依赖关系交由spring管理,避免硬编码造成的程序间过渡耦合

AOP面向切面编程

通过spring的AOP功能,方便实现面向切面编程,很多使用传统OOP编程不容易实现的业务功能,可以通过AOP轻松实现。比如事务管理,日志功能。

声明式事务管理

通过声明式方式灵活实现事务管理,提高开发效率和质量,将我们(程序员)从单调烦闷的事务管理代码中解脱出来

整合第三方优秀框架

spring框架降低了第三方框架的集成使用难度,提供了对各种框架(quartz、mybatis、springmvc等)的直接支持

spring框架体系结构
01_Spring【IOC+依赖注入】_第4张图片
image.png

spring 基于xml配置IOC

spring IOC介绍

IOC(Inversion Of Control)控制反转。指的是获取对象方式由原来主动获取,到被动接收的转变。在spring中,IOC就是工厂模式解耦,是spring框架用于创建对象和管理对象的容器。

官网

https://spring.io/

下载

http://repo.springsource.org/libs-release-local/org/springframework/spring/

搭建spring IOC环境
配置pom.xml


    4.0.0

    com.heaven
    spring-day01-03helloworld
    1.0-SNAPSHOT
    jar

    
    
        
        5.0.2.RELEASE
    

    
    
        
        
            org.springframework
            spring-context
            ${spring.version}
        
        
    
    

编写bean.xml



    
    

    
    


spring 工厂类结构

spring 工厂类结构
01_Spring【IOC+依赖注入】_第5张图片
image.png

spring bean标签

bean标签作用

bean标签作用:
配置javaBean对象。

spring框架遇到bean标签,默认调用无参数构造方法实例化对象。

bean标签属性
01_Spring【IOC+依赖注入】_第6张图片
image.png
bean作用范围和生命周期
01_Spring【IOC+依赖注入】_第7张图片
image.png
案例:

    
01_Spring【IOC+依赖注入】_第8张图片
image.png
singleton

    
01_Spring【IOC+依赖注入】_第9张图片
image.png
prototype
 
    
01_Spring【IOC+依赖注入】_第10张图片
image.png
init-method与destroy-method
配置bean.xml

    

spring 实例化bean三种方式

spring框架有三种创建对象的方式

无参数构造方法实例化(重点)

    
静态工厂方法实例化

编写工厂类

import com.heaven.dao.CustomerDao;
import com.heaven.dao.impl.CustomerDaoImpl;

/**
 * 学习静态工厂方法,实例化对象
 */
public class StaticFactoryBean {

    /**
     * 工厂方法,注意:static关键子。该方法是静态的
     */
    public static CustomerDao createCustomerDao(){

        // 返回结果
        CustomerDao customerDao = null;

        System.out.println("静态工厂方法实例化对象----------------------start");
        customerDao = new CustomerDaoImpl();
        System.out.println("静态工厂方法实例化对象----------------------end");

        return customerDao;
    }
}

配置bean.xml


    
实例工厂方法实例化

编写工厂类


import com.heaven.dao.CustomerDao;
import com.heaven.dao.impl.CustomerDaoImpl;

/**
 * 学习实例工厂方法,实例化对象
 */
public class InstanceFactoryBean {

    /**
     * 工厂方法,注意:该方法是一个普通方法
     */
    public  CustomerDao createCustomerDao(){

        // 返回结果
        CustomerDao customerDao = null;

        System.out.println("实例工厂方法实例化对象----------------------start");
        customerDao = new CustomerDaoImpl();
        System.out.println("实例工厂方法实例化对象----------------------end");

        return customerDao;
    }
}

配置bean.xml


    
    

spring依赖注入

依赖注入(Dependency Injection),它是spring框架核心IOC的具体实现。用于维护应用程序中,层与层之间、对象与对象之间的关系。

依赖注入就是给类的成员变量赋值。

两种类型(构造方法、set)

构造方法注入

通过构造方法,给类的成员变量赋值

编写构造方法注入
/**
 * 学习构造方法注入数据
 */
public class ConstructorDaoImpl implements CustomerDao{

    // 类的成员变量
    private int id;
    private String name;
    private Integer age;
    private Date birthday;

    //====================================构造方法=============================
    public ConstructorDaoImpl(int id, String name, Integer age, Date birthday) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }

    /**
     * 保存客户操作
     */
    public void saveCustomer() {
        System.out.println("id="+id+",name="+name+",age="+age+",birthday="+birthday);
    }
}

配置bean.xml

 
    
        
        
        
        
    

    
    

set方法注入

set方法注入,就是通过set方法,给类的成员变量赋值

编写set方法注入类

public class SetDaoImpl implements CustomerDao{

    // 类的成员变量
    private int id;
    private String name;
    private Integer age;
    private Date birthday;

    //====================================set方法=============================
    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    /**
     * 保存客户操作
     */
    public void saveCustomer() {
        System.out.println("id="+id+",name="+name+",age="+age+",birthday="+birthday);
    }
}

配置bean.xml


    
        
        
        
        
    

依赖注入简化配置方式

p名称空间注入和c名称空间注入
p:
01_Spring【IOC+依赖注入】_第11张图片
image.png
c:

    

集合属性依赖注入

成员变量是集合(MapListSet`Array)的赋值

编写集合类型成员变量类
public class CollectionDaoImpl implements CustomerDao {

    // 集合类型成员变量
    private String[] array;
    private List list;
    private Set set;

    private Map map;
    private Properties prop;

    //===========================================set方法
    public void setArray(String[] array) {
        this.array = array;
    }

    public void setList(List list) {
        this.list = list;
    }

    public void setSet(Set set) {
        this.set = set;
    }

    public void setMap(Map map) {
        this.map = map;
    }

    public void setProp(Properties prop) {
        this.prop = prop;
    }

    /**
     * 保存客户操作
     */
    public void saveCustomer() {
        System.out.println(array !=null? Arrays.asList(array):"");
        System.out.println(list);
        System.out.println(set);
        System.out.println(map);
        System.out.println(prop);
    }
}

配置bean.xml


    
        
        
            
                array1
                array2
            
        
        
        
            
                list1
                list2
            
        
        
        
            
                set1
                set2
            
        
        
        
            
                
                
            
        
        
        
            
                prop-v1
                prop-v2
            
        
    

spring基于注解配置IOC

客户dao实现类

@Component("customerDao")
public class CustomerDaoImpl implements CustomerDao {

    /**
     * 保存客户操作
     */
    public void saveCustomer() {
        System.out.println("保存客户操作。");
    }
}

改造service实现类

 */
@Component("customerService")
public class CustomerServiceImpl implements CustomerService {

    // 定义客户dao
    @Autowired
    private CustomerDao customerDao;

    /**
     * 保存客户操作
     */
    public void saveCustomer() {
        customerDao.saveCustomer();
    }
}

配置bean.xml




    
    

    

    



改造客户controller

/**
 * 客户controller
 */
public class CustomerController {

    public static void main(String[] args) {

        /**
         * 学习注解配置spring IOC:
         *      细节:
         *          1.在加载spring配置文件bean.xml,创建spring IOC容器的时候,需要加上(classpath:)
         *          2.从功能实现上,可以加上,也可以不加。spring框架建议我们加上
         */
        // 1.加载spring配置文件,创建spring ioc容器
        ApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean.xml");

        // 2.从容器中获取客户service对象
        CustomerService customerService = (CustomerService)context.getBean("customerService");

        // 保存客户
        customerService.saveCustomer();

    }
}

常用注解

创建对象相关的注解
@Component

作用:
配置javaBean对象。相当于xml配置方式中的bean标签

属性:
value:给bean一个唯一标识名称

细节:
1.value属性可以省略
2.默认使用类的名称首字母小写,作为bean的名称

@controller、@Service、@Repository

由@Component演化的三个注解:
@Controller:一般用于表现层
@Service:一般用于业务层
@Repository:一般用于持久层

scope

作用:
设置bean的作用范围,相当于xml配置方式中bean标签的scope属性。

属性:
value:指定作用范围取值
属性取值:
singleton:单例。默认值
prototype:多例。
request:web项目中,把bean对象存入request域中
session:web项目中,把bean对象存入全局session域中

注入数据相关的注解
@Autowired

作用:
默认按照bean的类型注入数据

属性:
required:指定目标bean是否必须存在于spring的IOC容器(true必须存在;false:可以不存在;默认true)

细节:
1.在spring容器中,如果同一个类型存在多个bean实例对象
2.则先按照bean的类型进行注入,再按照bean的名称进行匹配
3.匹配上注入成功;匹配不上注入失败

@Qualifier

作用:

与@Autowired注解一起使用,指定在按照bean类型注入的基础上,再按照bean的名称注入。

属性:
value,指定bean的名称。

细节:
1.在类的成员变量上,不能单独使用。需要与@Autowired注解一起使用。
2.在方法的成员变量上,可以单独使用。

@Resource

作用:
默认按照bean的名称注入数据。

属性:
name:指定bean的名称注入数据
type:指定bean的类型注入数据

细节:
默认按照bean的名称匹配注入数据。如果注入失败,再按照bean的类型注入

Value

给java简单数据类型注入数据。

与bean生命周期相关的注解
@PostConstruct

初始化操作,相当于xml配置方式中bean 标签的init-method属性

@PreDestroy

销毁操作,相当于xml配置方式中bean 标签的destroy-method属性

注解完整案例代码参考——

CustomerServiceImpl
/**
 * 客户service实现类,学习常用注解:
 *      1.创建对象相关的注解:
 *          @Component:
 *              作用:配置javaBean对象。相当于xml配置方式中的bean标签
 *              属性:
 *                  value:给bean一个唯一标识名称
 *              细节:
 *                  1.value属性可以省略
 *                  2.默认使用类的名称首字母小写,作为bean的名称
 *
 *           @Controller、@Service、@Repository:由@Component衍生的三个注解,衍生的目的是语义更加明确
 *              @Controller:一般用于表现层
 *              @Service:一般用于业务层
 *              @Repository:一般用于持久层
 *
 *      2.设置bean作用范围相关的注解:
 *          @Scope:
 *              作用:设置bean的作用范围。相当于xml配置方式中bean标签的scope属性
 *              属性:
 *                  value:指定作用范围取值
 *              属性取值:
 *                  singleton:单例。默认值
 *                  prototype:多例
 *                  request:web项目中,把bean对象存入request域中【了解】
 *                  session:web项目中,把bean对象存入session域中【了解】
 *                  globalsession:web项目中,把bean对象存入全局session域中【了解】
 *
 *      3.注入数据相关的注解:
 *          @Autowired:
 *              作用:默认按照bean的类型注入数据
 *              属性:
 *                  required:指定目标bean是否必须存在于spring的IOC容器(true必须存在;false:可以不存在;默认true)
 *              细节:
 *                  1.在spring容器中,如果同一个类型存在多个bean实例对象
 *                  2.则先按照bean的类型进行注入,再按照bean的名称进行匹配
 *                  3.匹配上注入成功;匹配不上注入失败
 *
 *          @Qualifier:
 *              作用:与@Autowired注解一起使用,指定在按照bean类型注入的基础上,再按照bean的名称注入
 *              属性:
 *                  value:指定bean的名称
 *              细节:
 *                  1.在类的成员变量上,不能单独使用。需要与@Autowired注解一起使用
 *                  2.在方法的成员变量上,可以单独使用
 *
 *          @Resource:
 *              作用:默认按照bean的名称注入数据
 *              属性:
 *                  name:指定bean的名称注入数据
 *                  type:指定bean的类型注入数据
 *               细节:
 *                  默认按照bean的名称匹配注入数据。如果注入失败,再按照bean的类型注入
 *
 *          @Value:
 *              作用:给java简单类型成员变量注入数据
 *
 *      4.与bean的生命周期相关的注解:
 *          @PostConstruct:
 *              初始化操作,相当于xml配置方式中bean标签的init-method属性
 *          @PreDestroy:
 *              销毁操作,相当于xml配置方式中bean标签的destroy-method属性
 *
 */
@Service("customerService")
@Scope(value = "singleton")
public class CustomerServiceImpl implements CustomerService {
    // 定义客户dao
    /*@Autowired
    @Qualifier(value = "customerDao1")*/
    //@Resource(name = "customerDao1")
    @Resource(type = CustomerDaoImpl.class)
    private CustomerDao customerDao;

    // java简单类型成员变量
    @Value("1")
    private int id;
    @Value("小明")
    private String name;

    /**
     * 初始化操作
     */
    @PostConstruct
    public void init(){
        System.out.println("正在执行初始化操作......");
    }

    /**
     * 销毁操作
     */
    @PreDestroy
    public void destroy(){
        System.out.println("正在执行销毁操作......");
    }

    /**
     * 保存客户操作
     */
    public void saveCustomer() {
        System.out.println("id="+id+",name="+name);
        customerDao.saveCustomer();
    }
}

CustomerController
/**
 * 客户controller
 */
public class CustomerController {

    public static void main(String[] args) {

        /**
         * 学习常用注解
         */
        // 1.加载spring配置文件,创建spring ioc容器
        //ApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean.xml");

        // 2.从容器中获取客户service对象
        /**
         * 创建对象相关的注解:@Component、@Controller、@Service、@Repository
         */
        /*CustomerService customerService = (CustomerService)context.getBean("customerService");*/

        /**
         * 设置bean的作用范围相关的注解:@Scope
         */
       /* CustomerService customerService = (CustomerService)context.getBean("customerService");
        CustomerService customerService1 = (CustomerService)context.getBean("customerService");

        System.out.println(customerService==customerService1);
        System.out.println(customerService.hashCode());
        System.out.println(customerService1.hashCode());*/

        /**
         * 注入数据相关的注解:@Autowired、@Qualifier、@Resource、@Value
         */
       /* CustomerService customerService = (CustomerService)context.getBean("customerService");*/

        /**
         * 与bean生命周期相关的注解:@PostConstruct、@PreDestroy
         */
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:bean.xml");

        CustomerService customerService = (CustomerService)context.getBean("customerService");

        // 保存客户
        customerService.saveCustomer();

        // 销毁容器
        context.close();

    }
}

你可能感兴趣的:(01_Spring【IOC+依赖注入】)