Spring第八课:带你了解一下IOC的底层原理 然后写出一个小的例子中的Demo
第一部分Spring框架的设计理念了解一下:
当你了解一个框架时,重要的是不仅要知道它做了什么,而且要知道它遵循什么原则。以下是 Spring Framework 的指导原则:
提供每个级别的选择。Spring 允许您尽可能晚地推迟设计决策。例如,您可以通过配置切换持久性提供程序,而无需更改代码。许多其他基础设施问题以及与第三方 API 的集成也是如此。
容纳不同的观点。Spring 拥抱灵活性,并且不会对事情应该如何做固执己见。它以不同的视角支持广泛的应用需求。
保持强大的向后兼容性。Spring 的演变经过精心管理,在版本之间几乎没有发生重大变化。Spring 支持精心挑选的一系列 JDK 版本和第三方库,以方便维护依赖于 Spring 的应用程序和库。
关心 API 设计。Spring 团队投入大量精力和时间来制作直观且可跨多个版本和多年使用的 API。
为代码质量设定高标准。Spring 框架非常强调有意义的、最新的和准确的 javadoc。它是极少数可以声称代码结构清晰且包之间没有循环依赖关系的项目之一。
第二部分理解 Spring IOC的概念是什么
IOC不是一种技术而是一种设计思想,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。 在传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对 象的创建; 何为控制反转? 传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象; 因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。
第三部分案例分析
方案一:传通的开发方式
package Com.ko.dao; public interface UserDao { void getUser(); }
package Com.ko.dao; public class UserDaoImpl implements UserDao { @Override public void getUser() { System.out.println("默认获取用户的数据信息"); } } package Com.ko.dao; public class UserDaoMysqlImpl implements UserDao{ @Override public void getUser() { System.out.println("MySql获取数据库的数据"); } }
package Com.ko.service; public interface UserService { void getUser(); }
package Com.ko.service; import Com.ko.dao.UserDao; import Com.ko.dao.UserDaoImpl; import Com.ko.dao.UserDaoMysqlImpl; public class UserServiceImpl implements UserService{ private UserDao userDao =new UserDaoImpl(); @Override public void getUser() { userDao.getUser(); } }
上面是传通的方式 利用了 new 关键字 你会发现你要常常的去改源码 不符合设计模式的理论
方案二: 做下操作改造一下:
package Com.ko.service; import Com.ko.dao.UserDao; import Com.ko.dao.UserDaoImpl; import Com.ko.dao.UserDaoMysqlImpl; public class UserServiceImpl implements UserService{ // private UserDao userDao; /** * 控制反转 * @param userDao */ //在原有的基础上加了一个Set方法 public void setUserDao(UserDao userDao) { this.userDao = userDao; } private UserDao userDao =new UserDaoImpl(); @Override public void getUser() { userDao.getUser(); } }
import Com.ko.dao.UserDaoImpl; import Com.ko.dao.UserDaoMysqlImpl; import Com.ko.service.UserService; import Com.ko.service.UserServiceImpl; import sun.rmi.transport.proxy.RMISocketInfo; public class MyTest { public static void main(String[] args) { //用户实际调用业务层 dao层不需要接触 UserService userService=new UserServiceImpl(); (( UserServiceImpl) userService).setUserDao(new UserDaoMysqlImpl()); userService.getUser(); } }
运行结果
第四部分IOC能做什么
1.IOC控制反转
IoC(Inversion of Control,控制反转)。这是spring的核心,贯穿始终。所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。而Spring提供了IOC容器来帮我们生成所需要的对象。也就是说在我们原先的对象中有用到其他对象的地方Spring会帮我们来注入。不用我们再去考虑这些问题。
2.DI(依赖注入)
spring提供了三种方式来依赖注入,有构造方法注入,setter方法注入以及接口注入。使用构造方法注入需要注意的一点就是要避免循环依赖。所谓的循环依赖指的就是在A对象的构造方法中Spring要注入B,而在B对象中Spring要注入A。这个时候会形成一个闭环因为Spring不知道该先注入哪一个接着会抛出异常。而Spring建议的处理方式是说如果遇到这种情况的话就改用Setter方式注入。 而spring就是通过反射来实现注入的。 理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”。 谁依赖谁:应用程序依赖于IoC容器; 为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源; 谁注入谁:IoC容器注入应用程序某个对象,应用程序依赖的对象; 注入了什么:注入某个对象所需要的外部资源(包括对象、资源、常量数据)
SpringIOC的第一个Demo本案例基于Maven项目开发
在Maven项目父工程中导入必要的依赖:
下面是导入Spring框架要的架包 之前是用架包的方式 现在统一用maven的依赖 一个原则 约定大于配置
官网的地址:https://mvnrepository.com/search?q=spring
下面是依赖的是junit架包:
官网的介绍
下面是依赖的是jdbc架包:
标题
上面maven坐标的官网地址:
Maven仓库中要的所有maven坐标https://mvnrepository.com/search?q=jdbc
配置文件:建议各位去官网中找 不要去复制 博客的博主的 毕竟学习是自己的事情 ,下面是步骤
官方的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" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="..." class="..."> <!-- collaborators and configuration for this bean go here --> </bean> <bean id="..." class="..."> <!-- collaborators and configuration for this bean go here --> </bean> <!-- more bean definitions go here --> </beans>
package Com.lop.pojo; public class Hello { private String str; //get set tostring 有参 无参 }
Hellow hellow =new Hello()
bean=对象 new Helo()
id=变量名
class=new 的对象
property 相当于属性设置了值
该id属性是标识单个 bean 定义的字符串。
该class属性定义 bean 的类型并使用完全限定的类名。
<bean id="hello" class="Com.lop.pojo.Hello"> <property name="str" value="spring"></property> </bean>
import Com.lop.pojo.Hello; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { public static void main(String[] args) { //获取Spring的上下文对象 ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); //我们的对象现在都在Spring中管理了 我们要使用 直接取出又可以 Hello hello = (Hello) context.getBean("hello"); System.out.println(hello.toString()); } }
标题
Hello{str='spring'} //str=spring咋来的?
初始Spring源码类的过程的大致过程:
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {}
public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext {}
public abstract class AbstractRefreshableConfigApplicationContext extends AbstractRefreshableApplicationContext implements BeanNameAware, InitializingBean {}
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {}
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {}
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {}
推荐两个官网:
https://mvnrepository.com/search?q=j
下一课官网