文章目录
Spring
(一)概述:
1.什么是Spring?
Spring是一个从实际开发中抽取出来的框架,因此它完成了大量开发中的通用步骤,留给开发者的仅仅是与特定应用相关的部分,从而大大提高了企业应用的开发效率。Spring使每个人都可以更快,更轻松,更安全地进行Java编程;Spring对速度,简单性和生产率的关注使其成为世界上最受欢迎的 Java框架。
Spring框架由 Rod Johnson 开发,他是悉尼大学的博士,然而他的专业不是计算机,而是音乐学,所以我们可以用心感受Spring中的优雅和魅力;2004年3月24日,发布了1.0正式版。
2.Spring官网
- https://spring.io
从官网我们可以找到Spring各类的参考文献和API文档:
3.Spring的优点
- 低侵入式设计,代码的污染极低;
- 独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere的承诺;
- Spring的IoC容器降低了业务对象替换的复杂性,提高了组件之间的解耦;
- Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式管理,从而提供了更好的复用;
- Spring的ORM和DAO提供了与第三方持久层框架的良好整合,并简化了底层的数据库访问;
- Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部。
(二)剖析IOC/DI:
1.什么是IoC/DI?
它Spring的核心技术之一,IoC(Inversion of Control)控制反转,是一种设计思想,DI(Dependency Injection)依赖注入,是实现IoC的一种方法,后来 Martine Fowler 为这种方式起了另一个名称即DI;在此过程中,对象仅通过构造函数参数,工厂方法的参数或在构造或从工厂方法返回后在对象实例上设置的属性来定义其依赖项(即,与它们一起使用的其他对象)。
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入。
2.看图说话
- 在没有IoC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,底层的实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑:(存在耦合)
- IoC容器将全部对象的控制权全部交由自己这个“第三方”,把复杂系统分解成相互合作的对象,这些对象类通过封装以后,内部实现对外部是透明的,从而降低了解决问题的复杂度,而且可以灵活地被重用和扩展。借助于“第三方”(IoC容器)实现具有依赖关系的对象之间的解耦,即控制反转后将对象的创建转移给第三方:
- 解耦后,拿掉IoC容器后的系统,就是我们要实现整个系统所需要完成的全部内容。这时候,A、B、C、D这4个对象之间已经没有了耦合关系,彼此毫无联系,这样,当你在实现A的时候,根本无须再去考虑B、C和D了,对象之间的依赖关系已经降低到了最低程度。所以,对于系统开发而言,这将是一件多么美好的事情,参与开发的每一成员只要实现自己的类就可以了,跟其他就没有任何关系了。
3.通过代码分析实现IoC
- 我们原来的方式:
- Dao层
定义接口:
public interface UserDao {
public void getUser();
}
定义接口的实现类:
public class UserDaoImpl implements UserDao {
@Override
public void getUser() {
System.out.println("获取用户数据");
}
}
- Service层
定义Service接口:
public interface UserService {
public void getUser();
}
定义Service的实现类:(在这里实现Dao层的方法)
public class UserServiceImpl implements UserService {
private UserDao userDao = new UserDaoImpl();
@Override
public void getUser() {
userDao.getUser();
}
}
测试:
用户调用的是业务层的实现类,用户不需要接触Dao层
@Test
public void test(){
UserService service = new UserServiceImpl();
service.getUser();
}
//结果:获取用户数据
- 新的需求:现在需要再增加一个实现类:(UserDaoMySqlImpl)
public class UserDaoMySqlImpl implements UserDao {
@Override
public void getUser() {
System.out.println("MySql获取用户数据");
}
}
此时如果我们需要使用这个实现类,就需要去Service层的实现类里面修改代码,从而得以实现:
public class UserServiceImpl implements UserService {
private UserDao userDao = new UserDaoMySqlImpl ();
@Override
public void getUser() {
userDao.getUser();
}
}
// 结果:MySql获取用户数据
- 发现问题:
假设我们如果再增加新的实现类,又需要去Service实现类里面修改代码,从而得以实现,这种方式就不适用了,每次变动,都需要修改大量代码,存在很大的耦合性,牵一发而动全身; - 解决问题:
我们可以在需要用的地方 , 不去实现它 , 而是留出一个接口 , 利用set实现:
public class UserServiceImpl implements UserService {
private UserDao userDao;
// set实现动态值的注入
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
@Override
public void getUser() {
userDao.getUser();
}
}
对应的测试类:
@Test
public void test(){
UserServiceImpl service = new UserServiceImpl();
//实现UserDaoMySqlImpl
service.setUserDao(new UserDaoMySqlImpl());
service.getUser();
//实现新的类
service.setUserDao(new UserDaoMySqlImpl2());
service.getUser();
/*
service.setUserDao(new xxxx());
service.getUser();
*/
}
总结:
以前所有东西都是由程序去控制创建,而现在是由我们自行控制创建对象,把主动权交给了调用者;程序不用去管怎么创建、怎么实现了,它只负责提供一个接口;这种思想,从本质上解决了问题,我们程序员不用去管理对象的创建了,更多的去关注业务的实现,耦合性大大降低 ,这也就是IOC的原型。
(三)创建一个Spring程序
- 通过依赖,导入Spring相关的jar包:
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
- 编写代码:
- 编写一个实体类
public class Hello {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("Hello,"+ name );
}
}
- 将实体类注入Spring文件中:
<?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就是java对象 , 由Spring创建和管理 -->
<bean id="hello" class="com.chen.pojo.Hello">
<!-- name就是属性, value就是赋的值 -->
<property name="name" value="Spring"/>
</bean>
</beans>
- 测试:
public void testHelloSpring(){
//解析你的.xml文件 , 生成管理相应的Bean对象
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//getBean : 参数即为spring配置文件中bean的id .
Hello hello = (Hello) context.getBean("hello");
hello.show();
}
//结果:Hello,Spring
总结:
hello 对象是由Spring创建的;
hello 对象的属性是由Spring容器设置的;
想要实现不同的操作,只需要在xml配置文件中进行修改,所谓的IoC即: 对象由 Spring 来创建、管理 、装配 。
//下篇再见…谢谢