一,Spring的IOC
–1,概述
IOC是指控制反转,是指把对象创建初始化销毁的权利都交给spring框架
–2,xml实现IOC步骤(不推荐)
–创建类
–创建核心配置文件spring-config.xml配置类的信息(bean)
–直接测试(从spring里直接getBean)
–3,注解实现IOC的步骤
–创建类(@Component)
package cn.tedu.spring;
public class Hello {
}
package cn.tedu.spring;
import org.springframework.stereotype.Component;
@Component//把这个类交给spring框架IOC(new)
public class Hello2 {
}
--创建核心配置文件spring-config.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--这个文件是spring框架的核心配置文件-->
<!--配置一个扫描器:就是扫描哪些类上有@Component注解的就new
base-package用来指定要扫描的包路径
-->
<context:component-scan base-package="cn.tedu.spring" />
</beans>
--测试getBean
package spring;
import cn.tedu.spring.Animal;
import cn.tedu.spring.Animal2;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test1 {
public static void main(String[] args) {
ClassPathXmlApplicationContext spring =
new ClassPathXmlApplicationContext(
"spring-config.xml");
Hello2 a = (Hello2) spring.getBean("hello2");
System.out.println(a);//cn.tedu.spring.Animal2@1df82230
//报错NoSuchBeanDefinitionException
//Hello类上没有使用@Component注解,spring容器不会new不会管理这个类
Hello a2 = (Hello) spring.getBean("hello");
System.out.println(a2);
}
}
--4,自己实现IOC
--封装Bean类,两个属性beanId(类名)+属性beanPath(类的全路径)
package cn.tedu.myioc;
//spring容器可以看成是bean容器
public class Bean {
private String beanId ;//类名Bean
private String beanPath ;//类的全路径cn.tedu.myioc.Bean
//constructors
public Bean() { }
public Bean(String beanId, String beanPath) {
this.beanId = beanId;
this.beanPath = beanPath;
}
//get/set
public String getBeanId() {
return beanId;
}
public void setBeanId(String beanId) {
this.beanId = beanId;
}
public String getBeanPath() {
return beanPath;
}
public void setBeanPath(String beanPath) {
this.beanPath = beanPath;
}
}
--IOC的核心实现,new对象 - Map<类名,类的对象>
package cn.tedu.myioc;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
//模拟spring实现ioc--控制反转(new)
public class MyIOC {
//1,有哪些bean--工程里有很多类,spring都当做bean看待,都存入list查询效率要高
List<Bean> beans = new ArrayList<>();
//1.1,对象的初始化 -- 要创建对象时,早都准备好了很多bean
public MyIOC() throws Exception {
Bean b1 = new Bean("user","cn.tedu.myioc.User");
Bean b2 = new Bean("dept","cn.tedu.myioc.Dept");
Bean b3 = new Bean("order","cn.tedu.myioc.Order");
//1.2,把准备好的bean存入list,方便后面查的快
Collections.addAll(beans,b1,b2,b3);
//1.3,完成ioc的过程
init();
}
//2,给bean们创建对象--控制反转IOC
//准备map,存数据 -- key是类的名字 value是这个类的对象
Map<String,Object> map = new ConcurrentHashMap<>();
public void init() throws Exception {
//2.1,遍历list,获取每个bean
for (Bean b : beans) {
//2.2,获取每个bean身上的beanId作为key存入map
String key = b.getBeanId();
//2.3,获取每个bean身上的beanPath进行反射创建对象,作为value存入map
Object value = Class.forName(b.getBeanPath()).newInstance();
map.put(key,value);//{"user"=new User(),"dept"=new Dept()}
}
}
//3,getBean()获取对象
public Object getBean(String leiming){
return map.get(leiming);
}
}
--创建三个空的类
package cn.tedu.myioc;
public class User { }
class Dept { }
class Order { }
--测试 - getBean("类名")去map里找value
package cn.tedu.myioc;
public class TestMyIOC {
public static void main(String[] args) throws Exception {
MyIOC mine = new MyIOC();
Object o1 = mine.getBean("user");
System.out.println(o1);//cn.tedu.myioc.User@54bedef2
Object o2 = mine.getBean("dept");
System.out.println(o2);//cn.tedu.myioc.Dept@5caf905d
Object o3 = mine.getBean("order");
System.out.println(o3);// cn.tedu.myioc.Order@27716f4
}
}
--5,总结:
--用Spring框架的IOC,只要把类上加@Component注解+配置扫描器
--我们模拟Spring的过程(4,自己实现IOC)多理解
二,Spring的DI
–1,概述
基于IOC的控制反转的功能,又提供了DI依赖注入.使用注解@Autowired
–2,用法
–用@Autowired注解实现对象间的依赖关系
–3,测试
–创建Student类
package cn.tedu.di;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Student {
private String name = “jack” ;
//di:是把相关的对象的信息,自动装配–相当于底层帮你给属性提供了get/set
@Autowired //自动装配
private Teacher teacher;
@Override
public String toString() {
return “Student{” +
“name=’” + name + ‘’’ +
‘}’;
}
}
--创建Teacher类
package cn.tedu.di;
import org.springframework.stereotype.Component;
@Component
public class Teacher {
String name = "Tony";
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
'}';
}
}
--测试类
package cn.tedu.di;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestDI {
public static void main(String[] args) {
ClassPathXmlApplicationContext spring =
new ClassPathXmlApplicationContext(
"spring-config.xml");
//按照类名去获取对象--类加了@Component注解spring就会ioc进行new
Student s = (Student)spring.getBean("student");
//打印了Student依赖的Teacher信息--就是DI的效果
//Student{name='jack', teacher=Teacher{name='Tony'}}
System.out.println(s);
Teacher t = (Teacher)spring.getBean("teacher");
System.out.println(t);//Teacher{name='Tony'}
}
}
--4,自己实现DI
--获取Student类里的所有属性(name/teacher)
--Class提供的getDeclaredFields
--判断哪个属性有@Autowired注解,就给哪个属性设置值new Teacher();
--遍历得到每个属性Field
--if(有注解){ f.set() f.get() }
--测试
package cn.tedu.di;
import org.springframework.beans.factory.annotation.Autowired;
import java.lang.reflect.Field;
//自己实现DI --模拟Autowired注解
public class TestMyDI {
public static void main(String[] args) throws Exception {
Class c = Class.forName("cn.tedu.di.Student");
// 获取Student类里的所有属性(name/teacher)
Field[] fs = c.getDeclaredFields();//暴力反射:public/default/private
// 遍历得到每个属性f
for (Field f : fs) {
// 判断哪个属性有@Autowired注解,就给哪个属性设置值new Teacher();
Autowired a = f.getAnnotation(Autowired.class);
if( a != null ){//有注解
Object obj = c.newInstance();
f.setAccessible(true); //开启私有也可以访问的权限
f.set(obj, new Teacher() ) ; //给属性设置值
}
}
}
}
扩展:
–1,SpringMVC源码分析
–前端控制器DispatcherServlet:接受请求(url和方法的匹配规则)和做出响应
–处理器映射器HandlerMapping:就是根据url找到对应的类对应的方法
–处理器适配器HandlerAdaptor:就是干活的(Controller-Service-Dao-db)
–视图解析器ViewResolver:就是准备网页上要展示数据的格式
–视图渲染View:给浏览器响应,在浏览器上做展示