1 学习顺序为:spring springmvc mybatis
Spring是一个轻量级容器框架
- 控制反转(IoC)
- 面向切面(AOP)
理念:使现有的技术更加容易使用,大杂烩,整合了现有的技术框架
SSH=Struct2+Spring+Hibernate
SSM=SpringMVC+Spring+Mybatis
中文文档:Spring Framework 中文文档 - Spring Framework 5.1.3.RELEASE Reference | Docs4dev
官方文档在这个链接https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html
Githubspring-projects/spring-framework: Spring Framework (github.com)
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.21</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.21</version> </dependency>
优点:
- 开源、免费的框架;
- 轻量级、非入侵式的框架
- 控制反转IoC,面向切面编程AOP
- 支持事务的处理,对框架整合的支持
总结一句话:Spring就是一个轻量级的控制反转IoC和面向切面编程AOP的框架
2 Spring组成及拓展
- 七大模块
- 现代化的java开发(基于spring的开发):构建一切–协调一切–连接一切
- Spring Boot
- 一个快速开发的脚手架
- 基于Springboot可以快速的开发单个微服务
- 约定大于配置
- Spring Cloud
- 基于spring boot实现的
- Spring Boot
- Spingboot的前提使完全掌握Spring和SpringMVC
- 弊端:配置地狱
3 IoC理论推导
原来的方式
- UserDao接口
public interface UserDao { void getUser(); }
- UserDaoImpl接口
public class UserDaoImpl implements UserDao { @Override public void getUser() { System.out.println("获取用户数据"); } }
- UserService业务接口
public interface UserService { public void getUser(); }
- UserServiceImpl接口
public class UserServiceImpl implements UserService { private UserDao userDao = new UserDaoImpl(); @Override public void getUser() { userDao.getUser(); } }
- 测试
@Test public void test(){ UserService service = new UserServiceImpl(); service.getUser(); }
- UserDaoMysqlImpl(Userdao 的实现类)
public class UserDaoMysqlImpl implements UserDao { @Override public void getUser() { System.out.println("Mysql获取用户数据"); } }
- 我们要去使用 MySql 的话,我们就需要去 service 实现类里面修改对应的实现:
// private UserDao userDao = new UserDaoImpl(); // private UserDao userDao = new UserDaoMysqlImpl(); // private UserDao userDao = new UserDaoOracleImpl();
- 在假设,我们再增加一个 Userdao 的实现类 UserDaoOracleImpl(Userdao 的实现类)
public class UserDaoOracleImpl implements UserDao { @Override public void getUser() { System.out.println("Oracle获取用户数据"); } }
修改之后的版本
- 之前的业务中,用户的需求可能会影响原来的代码,我们需要根据用户的需求去修改原代码
- 如果程序代码量十分大,修改一次的成本代价十分昂贵,这种设计的耦合性太高.
- 那我们如何去解决呢?
- 我们可以在需要用到他的地方,不去实现它,而是留出一个接口,利用 set , 我们去代码里修改下 .
- UserServiceImpl
public class UserServiceImpl implements UserService { private UserDao userDao; // 使用set进行动态实现值的注入,实现了IoC控制反转!!! public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public void getUser() { userDao.getUser(); } }
- 测试
@Test public void test() { UserServiceImpl service = new UserServiceImpl(); service.setUserDao(new UserDaoMysqlImpl()); service.getUser(); //那我们现在又想用Oracle去实现呢 service.setUserDao(new UserDaoOracleImpl()); service.getUser(); }
- 使用一个Set接口实现,已经发生了革命性的变化:
- 之前程序是主动创建对象,控制权在程序员手上!(用户每一个需求需要程序员去改代码)
- 使用了Set注入后,程序不再具有主动性,而是变成了被动的接收对象
- 这种思想,从本质上解决了问题,不用再去管理对象的创建了。系统的耦合性大大降低,可以更加专注业务的实现。这是IoC的原型。
IoC本质
- 控制反转IoC(Inversion of Control)是一种设计思想,DI(依赖注入)是实现IoC的一种方法。
- IoC 是 Spring 框架的核心内容,使用多种方式完美的实现了 IoC,可以使用 XML 配置,也可以使用注解,新版本的 Spring 也可以零配置实现 IoC。
- Spring 容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从 IoC 容器中取出需要的对象。
- 采用 XML 方式配置 Bean 的时候,Bean 的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean 的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
- IoC是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection, DI)。
Hello,Spring
- 导入 Jar 包
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.1.10.RELEASE</version> </dependency>
- Hello.java
public class Hello { private String str; public String getStr() { return str; } public void setStr(String str) { this.str = str; } @Override public String toString() { return "Hello{" + "str='" + str + '\'' + '}'; } }
- beans.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 http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--使用spring创建对象,在spring中成为Bean 类型 变量名 = new 类型(); id = 变量名 class = new 的对象 property 相当于对象中的属性,value就是给对象中的属性设置一个值 --> <bean id="hello" class="com.kuang.pojo.Hello"> <property name="str" value="Spring"></property> </bean> </beans>
- MyTest
public class MyTest { public static void main(String[] args) { //解析beans.xml文件 , 生成管理相应的Bean对象 // ClassPathXmlApplicationContext需要导入 //获取Spring的上下文对象 ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); //我们的对象都在Spring中管理,如果要使用,直接取出来即可。 //getBean : 参数即为spring配置文件中bean的id . Hello hello = (Hello) context.getBean("hello"); System.out.println(hello.toString()); } }
- Hello对象是Spring创建的;
- Hello对象的属性是Spring容器(也就是beans)设置的。
- 控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的。
- 反转:程序本身不创建对象,而变成被动的接收对象
- 依赖:就是利用set方法来进行注入的
- IoC是一种编程思想,由主动的编程变成被动的接收
- 到了现在,彻底不用去程序中主动改动了。如果想要实现不同操作,只需要在xml配置文件中进行修改,所谓的IoC,一句话搞定:对象由Spring来创建、管理、装配!
IoC创建对象的方式
- 代码案例
- 使用无参构造从创建构造
- 假设使用有参构造创建对象
- 根据index参数下标设置
- 根据参数名字设置
- 根据参数类型设置
- Spring容器在
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
就实例化了所有对象,随用随取.(在配置文件加载时,容器中管理的对象就都被创建了)
Spring配置
- 别名
<!--设置别名:在获取Bean的时候可以使用别名获取--> <alias name="userT" alias="userNew"/>
- Bean的配置
<!--bean就是java对象,由Spring创建和管理--> <!-- id 是bean的标识符,要唯一,如果没有配置id,name就是默认标识符 如果配置id,又配置了name,那么name是别名 name可以设置多个别名,可以用逗号,分号,空格隔开 如果不配置id和name,可以根据applicationContext.getBean(.class)获取对象; class是bean的全限定名=包名+类名 --> <bean id="hello" name="hello2 h2,h3;h4" class="com.kuang.pojo.Hello"> <property name="name" value="Spring"/> </bean>
- import:一般用于团队开发使用,可以将多个配置文件,导入合并为一个.
- 项目中多个人开发,分别负责不同的类开发,不同类注册在不同bean中,import可以合并.
- 使用总配置即可.
<import resource="{path}/beans.xml"/>
依赖注入
- 构造器注入
- Set方式注入(重点)
- 依赖注入:Set注入
- 依赖:bean对象的创建依赖于容器
- 注入:bean对象中的所有属性由容器来注入
- 环境搭建
- 复杂类型
- 真实测试对象
- 依赖注入:Set注入
- 拓展方式注入
xmlns:p="http://www.springframework.org/schema/p"
p命名空间注入,可以直接注入属性的值:propertyxmlns:c="http://www.springframework.org/schema/c"
c命名空间- 需要先导入约束,才能使用
- bean的作用域
- Singleton单例(Spring默认模式)
scope="Singleton"
- prototype原型,每次从容器中get,都会产生一个新对象
- request\session\appication,只在web开发中使用
- Singleton单例(Spring默认模式)
Bean的自动装配
自动装配是Spring满足Bean依赖的一种方式
Spring会在上下文中自动寻找,并自动给bean装配属性
有三种自动装配方式:
- XML显式配置
- java显式配置
- 隐式自动装配(重要)
环境搭建
- byName:自动去容器上下文找和自己对象Set方法后面的值对应的bean id,并且全局唯一
- byType:自动去容器上下文找和自己对象属性类型相同的bean,需要全局唯一
使用注解实现自动装配
导入约束
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
配置注解的支持
<context:annotation-config/>
@Autowired
- 直接在属性上使用,也可以在set方式上使用
- 使用autowired不用编写set方法,前提是自动装配的属性在IoC容器中存在且符合bytype
- 如果环境复杂,不能一个autowired完成,可以用@Qualifier(value=”xxx”)辅助
@Resource,或者@Resource(name=”xxx”)
@Nullable 这个字段可以为null
@Autowired和@Resource的区别
自动装配,都可以放在属性字段上
@Autowired必须要求对象存在
执行顺序不同:
- @Autowired默认通过byType,多个同类型时,采用byName;
- @Resource默认通过byName,如果找不到就byType
使用注解开发
- bean
- 属性如何注入
- 衍生的注解
- dao:@Repository
- service:@Service
- controller:@Controller
- 自动装载配置
- @Autowired
- @Nullable
- @Resource
- 作用域:@Scope(“Singleton”);@Scope(“prototype”)
- 小结:
- xml更加万能,适用于任何场合,维护简单方便
- 注解:不是自己的类,使用不了,维护相对复杂
- 最佳实践:
- xml用来管理bean
- 注解用来完成属性的注入
- 使用过程中,只需要注意一个问题:必须让注解生效,就要开启注解支持
使用Java的方式配置Spring
- 使用多个注解@Component、@Beans,完成xml的功能
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达,可以邮件至 963614756@qq.com。