发表于: 2018-03-19 20:08:40

2 534


spring中的IOC是什么,为什么要使用IOC而不是new来创建实例

1 背景介绍

spring是什么?

    一个为了解决企业应用开发的复杂性而创建的开源框架,一个轻量级的控制反转(IOC)面向切面(AOP)的容器框架

2 知识剖析

spring中的IOC是什么意思?

    spring通过IOC即反转控制促进了松耦合,一个对象依赖的其他对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖的对象

为什么要使用IOC而不是new来创建实例?

    调用者直接使用new创建被调用者的实例,两者之间的耦合度很高

要由调用者亲自创建被调用者的实例对象,不利于软件的移植与维护

3 常见问题

IOC有哪些缺点?

    创建对象的步骤变复杂了

    通过反射来创建对象,会造成效率上的损耗

    缺少IDE重构的支持,如果修改了类名还需要到XML文件中手动修改

4 解决方案

    相比IOC的灵活性和可维护性来说,这点缺点可以忍受

5 编码实战

一个配置文件

<?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">

   <!-- Initialization for data source -->
   <bean id="dataSource"
         class="org.springframework.jdbc.datasource.DriverManagerDataSource">
       <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
       <property name="url" value="jdbc:mysql://localhost:3306/mydatabases"/>
       <property name="username" value="root"/>
       <property name="password" value="root"/>
   </bean>

   <!-- Definition for studentJDBCTemplate bean -->
   <bean id="studentJDBCTemplate"
         class="com.StudentJDBCTemplate">
       <property name="dataSource"  ref="dataSource" />
   </bean>

</beans>

负责实现的主函数(进行了创建和修改两种操作)

package com;

import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.StudentJDBCTemplate;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
       StudentJDBCTemplate studentJDBCTemplate = (StudentJDBCTemplate)context.getBean("studentJDBCTemplate");
       System.out.println("Records Creation");
       studentJDBCTemplate.create("韩",12);
//        List<Student> students = studentJDBCTemplate.listStudents();
//        for (Student record:students) {
//            System.out.println("ID:" + record.getId());
//            System.out.println(", Name : " + record.getName());
//        }
       System.out.println("update start");
       studentJDBCTemplate.update(12,"韩大师");
//        studentJDBCTemplate.delete(12);
   }
}

JDBCTemplate

package com;

import java.util.List;
import javax.sql.DataSource;
import org.springframework.jdbc.core.JdbcTemplate;

public class StudentJDBCTemplate implements StudentDAO{
private DataSource dataSource;
   private JdbcTemplate jdbcTemplateObject;
   public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
       this.jdbcTemplateObject = new JdbcTemplate(dataSource);
   }
public void create(String name,Integer ID) {
String SQL = "insert into student (name,ID) values (?,?)";
       jdbcTemplateObject.update(SQL,name,ID);
       return;
   }

//    @Override
//    public Student getStudent(Integer ID) {
//        String SQL = "select * from student where id = ?";
//        Student student = jdbcTemplateObject.query(SQL,new Object[]{ID}, new StudentMapper());
//        return student;
//    }
   
   @Override
   public List<Student> listStudents() {
String SQL = "select * from student";
       List<Student> students = jdbcTemplateObject.query(SQL,new StudentMapper());
       return students;
   }

@Override
   public void delete(Integer ID) {
String SQL = "delete from student where ID = ?";
       jdbcTemplateObject.update(SQL,ID);
       System.out.println("Deleted Record with ID =" + ID);
       return;
   }

@Override
   public void update(Integer ID, String name) {
String SQL = "update student set name = ? where ID = ?";
       jdbcTemplateObject.update(SQL,name,ID);
       System.out.println("Updated Record with ID = "+ ID);
       return;
   }
}


6 扩展思考

spring控制反转是控制什么反转

    IOC控制反转,强调容器的作用,用于组织或控制容器内bean的运行,把传统上有程序代码直接操控的对象的调用权交给容器

7 参考文献

    w3cschool spring 概述

    百度

8 更多讨论

什么是bean?

    由IOC容器管理的那些组成应用程序的对象就是bean,是由spring容器初始化,装配以及管理的对象。

9 提问

spring的依赖注入有什么优势?

spring的依赖注入有四种方式:Setter方法注入;构造方法注入;静态工厂的方法注入;实例工厂的方法注入

让使用者不需要自己去创建或获取自己的依赖,既然创建或获取的过程不是使用者控制的,这也就意味着,当我需要切换依赖时,不需要改变使用者的代码

@Autowired和@Resource的区别?

@Autowired  默认按类型装配   

 依赖对象必须存在,如果要允许null值,可以设置它的required属性为false   @Autowired(required=false)

 也可以使用名称装配,配合@Qualifier注解

@Resource  默认按名称进行装配,通过name属性进行指定

大白话解释,@Autowired自动注解,举个例子吧,一个类,俩个实现类,Autowired就不知道注入哪一个实现类,而Resource有name属性,可以区分。

By Type和 By Name的区别?

byName 通过参数名 自动装配,如果一个bean的name 和另外一个bean的 property 相同,就自动装配。

byType   通过参数的数据类型自动自动装配,如果一个bean的数据类型和另外一个bean的property属性的数据类型兼容,就自动装配

spring注入bean的方式有哪些?

使用属性的setter方法注入(最常用)

首先要配置被注入的bean,在该bean对应的类中,应该有要注入的对象属性或者基本数据类型的属性。

UserBiz类注入UserDAO,同时为UserBiz注入基本数据类型String,那么这时,就要为UserDAO对象和String类型设置setter方法.,用于进行依赖注入。

如何配置该bean呢?

<bean id="userBiz" class="com.text.biz.impl.UserBizImpl">

<property name="userDao">

<ref>userDao</ref>

</property>

</bean>

使用构造器注入

第一,在PersonBiz类中注入PersonDAO和一个String类型的数据;在该类中,不用为PersonDAO属性和String数据类型的属性设置setter方法,但是需要生成该类的构造方法;

第二,在配置文件中配置该类的bean,并配置构造器,在配置构造器中用到了<constructor-arg>节点,该节点有四个属性:

· index是索引,指定注入的属性,从0开始,如:0代表personDao,1代表str属性;

· type是指该属性所对应的类型,如Persondao对应的是com.aptech.dao.PersonDAO;

· ref 是指引用的依赖对象;

· value 当注入的不是依赖对象,而是基本数据类型时,就用value;

使用字段(Filed)注入(用注解方式)




返回列表 返回列表
评论

    分享到