1 背景介绍
spring是什么?
一个为了解决企业应用开发的复杂性而创建的开源框架,一个轻量级的控制反转(IOC)面向切面(AOP)的容器框架
2 知识剖析
spring中的IOC是什么意思?
spring通过IOC即反转控制促进了松耦合,一个对象依赖的其他对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖的对象
为什么要使用IOC而不是new来创建实例?
调用者直接使用new创建被调用者的实例,两者之间的耦合度很高
要由调用者亲自创建被调用者的实例对象,不利于软件的移植与维护
3 常见问题
IOC有哪些缺点?
创建对象的步骤变复杂了
通过反射来创建对象,会造成效率上的损耗
缺少IDE重构的支持,如果修改了类名还需要到XML文件中手动修改
4 解决方案
相比IOC的灵活性和可维护性来说,这点缺点可以忍受
5 编码实战
一个配置文件
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">
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
class="com.StudentJDBCTemplate">
负责实现的主函数(进行了创建和修改两种操作)
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 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 listStudents() {
String SQL = "select * from student";
List 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呢?
userDao
使用构造器注入
第一,在PersonBiz类中注入PersonDAO和一个String类型的数据;在该类中,不用为PersonDAO属性和String数据类型的属性设置setter方法,但是需要生成该类的构造方法;
第二,在配置文件中配置该类的bean,并配置构造器,在配置构造器中用到了节点,该节点有四个属性:
· index是索引,指定注入的属性,从0开始,如:0代表personDao,1代表str属性;
· type是指该属性所对应的类型,如Persondao对应的是com.aptech.dao.PersonDAO;
· ref 是指引用的依赖对象;
· value 当注入的不是依赖对象,而是基本数据类型时,就用value;
使用字段(Filed)注入(用注解方式)