
一、Spring是什么轻量级一站式框架简化JavaEE开发涵盖Web、数据访问、事务管理等各层技术无需依赖重量级服务器如EJB。核心优势解耦通过IoC容器管理对象依赖高效整合无缝集成MyBatis等主流框架模块化设计按需选择Spring模块Core、AOP、Data等和SpringBoot的关系核心目标Spring提供 IoC控制反转和 AOP面向切面编程等基础功能解决企业级开发的复杂性。SpringBoot简化 Spring 应用的搭建和配置减少 XML 和样板代码实现快速启动和开箱即用。依赖关系Spring 应用需手动配置大量组件如数据源、MVC、安全等而 SpringBoot 通过自动配置简化这一过程。SpringBoot基于 Spring 框架构建必须依赖 Spring 的核心模块如spring-context、spring-beans。开发体验Spring需编写大量配置类或 XML 文件依赖管理繁琐。SpringBoot通过SpringBootApplication和Starter 依赖自动装配组件实现零配置启动。Spring生态定位Spring Framework是基石Spring Boot简化配置Spring Cloud构建微服务二、IoC与DI1. 核心思想IoC将对象的创建权从程序员反转给Spring容器DI由容器动态建立对象间的依赖关系Setter/构造器注入!-- 传统方式硬编码创建 -- BookDao bookDao new BookDaoImpl(); !-- IoC方式容器创建 -- bean idbookDao classcom.example.BookDaoImpl/2.IOCInversion of Control控制反转(1)什么是控制反转呢使用对象时由主动new产生对象转换为由外部提供对象此过程中对象创建控制权由程序转移到外部此思想称为控制反转。业务层要用数据层的类对象以前是自己new的现在自己不new了交给别人[外部]来创建对象别人[外部]就反转控制了数据层对象的创建权这种思想就是控制反转(2)Spring和IOC之间的关系是什么呢?Spring技术对IOC思想进行了实现Spring提供了一个容器称为IOC容器用来充当IOC思想中的外部IOC思想中的别人[外部]指的就是Spring的IOC容器(3)IOC容器的作用以及内部存放的是什么?IOC容器负责对象的创建、初始化等一系列工作其中包含了数据层和业务层的类对象被创建或被管理的对象在IOC容器中统称为BeanIOC容器中放的就是一个个的Bean对象(4)当IOC容器中创建好service和dao对象后程序能正确执行么?不行因为service运行需要依赖dao对象IOC容器中虽然有service和dao对象但是service对象和dao对象没有任何关系需要把dao对象交给service,也就是说要绑定service和dao对象之间的关系3.DIDependency Injection依赖注入(1)什么是依赖注入呢?在容器中建立bean与bean之间的依赖关系的整个过程称为依赖注入。业务层要用数据层的类对象以前是自己new的现在自己不new了靠别人[外部其实指的就是IOC容器]来给注入进来这种思想就是依赖注入(2)IOC容器中哪些bean之间要建立依赖关系呢?这个需要程序员根据业务需求提前建立好关系如业务层需要依赖数据层service就要和dao建立依赖关系4.具体实现介绍完Spring的IOC和DI的概念后我们会发现这两个概念的最终目标就是充分解耦具体实现靠:使用IOC容器管理beanIOC)在IOC容器内将有依赖关系的bean进行关系绑定DI最终结果为使用对象时不仅可以直接从IOC容器中获取并且获取到的bean已经绑定了所有的依赖关系.5. 依赖注入方式类型配置示例适用场景Setter注入property namedao refbookDao/灵活推荐首选构造器注入constructor-arg refbookDao/强制依赖场景自动装配bean autowirebyType/简化配置按类型匹配关于Setter注入对于引用数据类型使用的是property name ref/对于简单数据类型使用的是property name value/配置文件的编写配置相对麻烦因此可以采用自动装配。IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配自动装配方式有哪些?按类型常用按名称按构造方法不启用自动装配三、Bean0.Bean基础配置bean idbean的唯一标识 classbean的类全名 scopebean的作用范围有singleton(默认)和prototype name为bean取的别名/整个配置中最常用的就两个属性id和class1. Bean作用域bean scopesingleton/ !-- 默认单例复用对象 -- bean scopeprototype/ !-- 非单例每次请求新对象 --单例优点减少对象创建开销提升性能多例场景有状态对象如含成员变量的域对象思考为什么bean默认为单例?bean为单例的意思是在Spring的IOC容器中只会有该类的一个对象bean对象只有一个就避免了对象的频繁创建与销毁达到了bean对象的复用性能高bean在容器中是单例的会不会产生线程安全问题?如果对象是有状态对象即该对象有成员变量可以用来存储数据的因为所有请求线程共用一个bean对象所以会存在线程安全问题。如果对象是无状态对象即该对象没有成员变量没有进行数据存储的因方法中的局部变量在方法调用完成后会被销毁所以不会存在线程安全问题。哪些bean对象适合交给容器进行管理?表现层对象业务层对象数据层对象工具对象哪些bean对象不适合交给容器进行管理?封装实例的域对象因为会引发线程安全问题所以不适合。2. Bean生命周期初始化顺序1. 构造方法 → 2. 属性注入 → 3. InitializingBean.afterPropertiesSet() → 4. 自定义init-method触发销毁ctx.close(); // 立即关闭容器 ctx.registerShutdownHook(); // JVM关闭前自动回调销毁顺序1. DisposableBean.destroy() → 2. 自定义destroy-method3. Bean实例化三种方式方式实现构造方法默认bean classcom.example.BookDaoImpl/静态工厂bean factory-methodcreate classcom.example.Factory/实例工厂FactoryBean接口实现FactoryBeanT重写getObject()整合第三方框架常用1构造方法测试函数public interface BookDao { public void save(); } public class BookDaoImpl implements BookDao { public BookDaoImpl() { System.out.println(book dao constructor is running ....); } public void save() { System.out.println(book dao save ...); } }可将public BookDaoImpl()改成private BookDaoImpl()也能执行成功。说明内部走的依然是构造函数,能访问到类中的私有构造方法。显而易见 Spring底层用的是反射。applicationContext.xml配置Spring容器?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beans xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd bean idbookDao classcom.mytest.dao.impl.BookDaoImpl/ /beans编写运行程序public class AppForInstanceBook { public static void main(String[] args) { ApplicationContext ctx new ClassPathXmlApplicationContext(applicationContext.xml); BookDao bookDao (BookDao) ctx.getBean(bookDao); bookDao.save(); } }输出因为每一个类默认都会提供一个无参构造函 数所以其实真正在使用这种方式的时候我们什么也不需要做。这也是我们以后比较常用的一种方式。2静态工厂在spring的配置文件application.properties中添加以下内容:bean idorderDao classcom.mytest.factory.OrderDaoFactory factory-methodgetOrderDao/class:工厂类的类全名factory-mehod:具体工厂类中创建对象的方法名在工厂的静态方法中我们除了new对象还可以做其他的一些业务操作这些操作必不可少比如日志等业务操作。具体实现代码略这种方式一般是用来兼容早期的一些老系统所以了解为主。3实例工厂FactoryBean实例工厂实例化配置的过程还是比较复杂所以spring为了简化这种配置方式就提供了一种叫 FactoryBean的方式来简化开发。创建一个UserDaoFactoryBean的类实现FactoryBean接口重写接口的方法public class UserDaoFactoryBean implements FactoryBeanUserDao { //代替原始实例工厂中创建对象的方法 public UserDao getObject() throws Exception { return new UserDaoImpl(); } //返回所创建类的Class对象 public Class? getObjectType() { return UserDao.class; } }在Spring的配置文件中进行配置之后AppForInstanceUser运行类不用做任何修改直接运行即可。bean iduserDao classcom.mytest.factory.UserDaoFactoryBean/查看源码会发现FactoryBean接口其实会有三个方法分别是://方法一:getObject()被重写后在方法中进行对象的创建并返回 T getObject() throws Exception; //方法二:getObjectType(),被重写后主要返回的是被创建类的Class对象 Class? getObjectType(); //方法三:默认单例将return重写false即可改成非单例 default boolean isSingleton() { return true; }这些方式中重点掌握构造方法和FactoryBean即可。需要注意的一点是构造方法在类中默认会提供但是如果重写了构造方法默认的就会消失在使 用的过程中需要注意如果需要重写构造方法最好把默认的构造方法也重写下。四、依赖注入高级技巧0.相关属性1. 集合注入!-- List注入 -- property namelist list valueJava/value ref beanobj1/ !-- 引用其他Bean -- /list /property !-- Map注入 -- property namemap map entry keyport value8080/ entry keydb value-refdataSource/ /map /propertyproperty标签表示setter方式注入构造方式注入constructor-arg标签内部也可以写array、list、set、map、props标签List的底层也是通过数组实现的所以list和array标签是可以混用集合中要添加引用类型只需要把value标签改成ref标签这种方式用的比较少2. 解决依赖冲突按类型自动装配容器中同类型Bean必须唯一按名称装配属性名需与Bean的id匹配耦合度高慎用五、小结1什么IOC/DI思想?IOC:控制反转控制反转的是对象的创建权DI:依赖注入绑定对象与对象之间的依赖关系2什么是IOC容器?Spring创建了一个容器用来存放所创建的对象这个容器就叫IOC容器3什么是Bean?容器中所存放的一个个对象就叫Bean或Bean对象。