当前位置:   article > 正文

Spring框架_spring 6.1

spring 6.1

目录

1、Spring

1.1 简介

1.2 Spring优点

1.3 组成 

1.4 扩展

2、IOC 

2.1 IOC理论推导

2.2 IOC本质

3、HelloSpring

4、IOC创建对象的方式

5、Spring配置

5.1 别名

5.2 Bean配置

5.3 import

6、注入(DI)

6.1 构造器注入

6.2 set方式注入

​编辑6.3 扩展注入

6.4 作用域

7、Bean的自动装配(autowire)

7.1 byName自动装配 

7.2 byType自动装配

7.3 使用注解实现自动装配

8、使用注解开发 

属性如何注入:

​编辑

衍生的注解:

作用域:

9、使用JavaConfig实现配置

10、代理模式

静态代理模式:

动态代理模式:

11、AOP

11.1 什么是AOP

11.2 AOP在Spring中的作用


1、Spring

1.1 简介

  • Spring:英文翻译为春天。在软件行业是什么意思呢?Spring给软件行业带来了春天。
  • 2002,首次推出了Spring框架的雏形:interface21框架!
  • Spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于2004年3月24日, 发布了1.4正式版。
  • Rod Johnson,SpringFramework创始人,著名作者,他的介绍:很难想象SpringFramework的学历,真的让好多人大吃一惊,他是悉尼大学的博士,然而他的专业不是计算机。而是音乐学。
  • Spring理念:使现有的技术更加容易使用,本身是一个大杂烩,整合了现有的技术框架!
  • SSM:SpringMVC+Spring+Mybatis。

官网:

Spring Framework

使用Spring前事先导入需要的jar包:

  1. <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-webmvc</artifactId>
  5. <version>5.3.14</version>
  6. </dependency>

1.2 Spring优点

Spring是一个开源的免费的框架(容器思想),同时它也是一个生态!

Spring是一个轻量级,非入侵式的框架!

控制反转(IOC),面向切面编程(AOP)!

支持事务的处理,对框架整合的支持!

Spring的开放性,并不强制应用完全依赖于Spring,开发者可以自由选择Spring的部分或全部!

总的一句话Spring就是一个轻量级控制反转(IOC),和面向切面编程(AOP)的框架。

1.3 组成 

1.4 扩展

在Spring的官网有这样个介绍:现代化的Java开发!(就是基于Spring的开发)

 Spring Boot 介绍:

  • 一个快速开发的脚手架。
  • 基于Spring Boot 可以快速的开发单个的微服务。
  • 约定大于配置(跟我们学的maven差不多)。

Spring Cloud介绍:

  • Spring Cloud是基于Spring Boot实现的。

为什么要学习Spring?

因为现在大多数的公司都在使用Spring Boot进行快速开发,学习Spring Boot的前提,则需要完全掌握Spring 及SpringMVC!相当于承上启下的作用!

弊端:发展了太久之后,违背了原来的理念!配置十分繁琐,人称:"配置地狱"!

2、IOC 

2.1 IOC理论推导

通过我们原来的MVC结构实现:

之前的结构:

  • Dao层—Daoimpl
  • service层—serviceimpl

我们当时进行这些Dao层的调用比较复杂,都是通过用户的需求,然后我们程序员在进行业务层的修改。

控制权在我们程序员手上。

这样的修改成本十分的昂贵。为什么呢?因为一旦代码量多了,那么我们程序员修改成本就会变得很高。

现在有一个思想上的革命:

我们使用一个Set接口实现:

  1. // 利用set进行动态实现值的注入
  2. public void setDaoUser(DaoUser daoUser) {
  3. this.daoUser = daoUser;
  4. }

这时候控制权会在用户手上。

之前,程序是主动创建对象!控制权在程序员手上!

使用set注入后,程序不在具有主动性,而是变成了被动的接收对象!

这种思想,从本质上解决了问题,我们程序员不用再去管理对象的创建了。系统的耦合性大大降低,我们可以更加专注的在业务的实现上!

2.2 IOC本质

控制反转IOC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IOC的一种方法,也有人认为DI只是IOC的另一种说法。没有IOC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。

 我们采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

什么是控制反转?

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的IOC容器。其实现方法是依赖注入(Dependency injection ,DI)。

3、HelloSpring

  • Hello对象是由Spring创建的。
  • Hello对象的属性是由Spring容器设置的。

这个过程就叫做控制反转:

控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的。

反转:程序本身不创建对象,而变成被动的接受对象。

依赖注入:就是利用set方法来进行注入的。

IOC是一种编程思想,由主动的编程变成被动的接受。

我们可以通过new ClassPathXmlApplicationContext去浏览一下底层源码。

到了现在,我们可以彻底不用在程序中去改动了,要实现不同的操作,只需要在xml配置文件中进行修改,所谓的IOC,一句话搞定:对象由Spring来创建,管理,装配!

bean容器的三步思想:

1、创建实体类

实体类里面写上getter、setter方法、toString();

2、创建bean.xml

以前创建对象都是通过new对象来创建, Hello hello = new Hello(); 现在有我们的bean来创建对象。

id = 变量名 class = new 的对象

property(相当于给属性设置一个值) name = 设置的属性名,value = 传递的参数

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd">
  6. <bean id="hello" class="com.lei.pojo.Hello">
  7. <property name="str" value="Spring"/>
  8. </bean>
  9. </beans>

3、测试

  1. public static void main(String[] args) {
  2. // 获取spring上下文对象
  3. ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
  4. // 通过context获取bean容器,提示:在这里使用哪个bean就需要强转该bean的类型
  5. Hello hello = (Hello)context.getBean("hello");
  6. // 输出hello.toString()方法。对应xml中给str设置的值
  7. System.out.println(hello.toString());
  8. }

输出结果:

 4、扩展

ref是代表,我要使用哪个bean就把哪个bean的id名放到ref中,供bean调用。

  1. <bean id="userImplDao" class="com.lei.pojo.Hello">
  2. <property name="daoUser" ref="userImplDao"></property>
  3. </bean>

4、IOC创建对象的方式

方式一:使用无参构造创建对象,默认的!

方式二:假设我们要使用有参构造创建对象。

三种方式:

  1. 下标赋值
  2. 类型
  3. 参数名
  1. <!--
  2. 第一种,下标赋值
  3. -->
  4. <bean id="user" class="com.lei.pojo.User">
  5. <constructor-arg index="0" value="张三"/>
  6. </bean>
  7. <!--第二种方式,通过类型创建,不建议使用,因为如果参数是两个String类型的就不可使用了-->
  8. <bean id="user" class="com.lei.pojo.User">
  9. <constructor-arg type="java.lang.String" value="李四"/>
  10. </bean>
  11. <!--第三中方式,通过参数名来设置-->
  12. <bean id="user" class="com.lei.pojo.User">
  13. <constructor-arg name="name" value="赵五"/>
  14. </bean>

总结:在配置文件加载的时候,容器中管理的对象就已经被初始化了。

5、Spring配置

5.1 别名

提示:别名,如果配置了别名,我们也可以通过别名来获取到对象。

<alias name="user" alias="newUser"/>

5.2 Bean配置

id:bean的唯一标识符,也就是相当于我们学的对象名。

class:bean对象所对应的全限定名:包名+类型。

name:也是别名,而且name可以同时取多个别名。

  1. <bean id="userT" class ="com.lei.pojo.userT" name="user2 u2,u3;u4">
  2. <property name="name" value="张三"/>
  3. </bean>

5.3 import

import,一般用于团队开发使用,他可以将多个配置文件,导入合并为一个。

假设,现在项目中有多个人开发,这三个人负责不同的类开发,不同的类需要注册在不同的bean中,我们可以利用import将所有人的beans.xml合并为一个总的!

  1. <import resource="beans.xml">
  2. <import resource="beans2.xml">
  3. <import resource="beans3.xml">

使用的时候,直接使用总的配置就可以了。

6、注入(DI)

6.1 构造器注入

利用构造函数为对象中的属性注入值,需要在xml配置文件中进行手动的配置。

6.2 set方式注入

Set注入指的就是在接受注入的类中定义一个要被注入的类型的一个set方法,并在参数中定义需要注入的元素。

6.2.1 搭建环境

复杂类型注入:

1、创建实体类 Address

  1. package com.lei.pojo;
  2. public class Address {
  3. private String address;
  4. // get.set方法
  5. }

2 、创建实体类 Student

  1. import java.util.*;
  2. public class Student {
  3. private String name;
  4. private Address address;
  5. private String[] books;
  6. private List<String> hobbys;
  7. private Map<String,String> card;
  8. private Set<String> games;
  9. private String wifi;
  10. private Properties info;
  11. }// get、set、toString方法

3、创建bean.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd">
  6. <bean id="student" class="com.lei.pojo.Student">
  7. <!--第一种,使用普通方法注入-->
  8. <property name="name" value="张三"/>
  9. </bean>
  10. </beans>

4、测试类

  1. public class MyTest {
  2. public static void main(String[] args) {
  3. ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
  4. Student student = (Student)context.getBean("student");
  5. System.out.println(student.toString());
  6. }
  7. }

6.2.2 复杂类型注入

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd">
  6. <bean id="address" class="com.lei.pojo.Address">
  7. <property name="address" value="中国"/>
  8. </bean>
  9. <bean id="student" class="com.lei.pojo.Student">
  10. <!--第一种,使用普通方法注入-->
  11. <property name="name" value="张三"/>
  12. <!--第二种,Bean注入:ref-->
  13. <property name="address" ref="address"/>
  14. <!--数组-->
  15. <property name="books">
  16. <array>
  17. <value>法律听讲</value>
  18. <value>哈佛听讲</value>
  19. <value>津大听讲</value>
  20. </array>
  21. </property>
  22. <!--list-->
  23. <property name="hobbys">
  24. <list>
  25. <value>听音乐</value>
  26. <value>打篮球</value>
  27. <value>唱歌</value>
  28. </list>
  29. </property>
  30. <!--Map-->
  31. <property name="card">
  32. <map>
  33. <entry key="身份证" value="111111222222223333"></entry>
  34. <entry key="ID卡" value="123123123"></entry>
  35. </map>
  36. </property>
  37. <!--Set-->
  38. <property name="games">
  39. <set>
  40. <value>lol</value>
  41. <value>bob</value>
  42. <value>coc</value>
  43. </set>
  44. </property>
  45. <!--wifi-->
  46. <property name="wifi">
  47. <null/>
  48. </property>
  49. <!--props-->
  50. <property name="info">
  51. <props>
  52. <prop key="name">张三</prop>
  53. <prop key="id">12311</prop>
  54. <prop key="pwd">123456</prop>
  55. </props>
  56. </property>
  57. </bean>
  58. </beans>

注入结果 

6.3 扩展注入

我们可以通过p命名空间和c命名空间进行注入:

  1. <bean id="user" class="com.lei.pojo.User" p:age="18" p:name="张三"/>
  2. <bean id="user2" class="com.lei.pojo.User" c:age="20" c:name="李四"/>

注意点:在使用p命名空间和c命名空间的时候要添加约束名!

添加到beans里面:

  1. xmlns:p="http://www.springframework.org/schema/p"
  2. xmlns:c="http://www.springframework.org/schema/c"

6.4 作用域

 1.单例模式(也是spring默认机制)singleton。

<bean id="user2" class="com.lei.pojo.User" c:age="20" c:name="卬轩" scope="singleton"/>

2.原型模式(每次从容器中get的时候,都会产生出一个新对象)prototype。

<bean id="user2" class="com.lei.pojo.User" c:age="20" c:name="卬轩" scope="prototype"/>

3.Request、Session、application、这些只能在web开发中使用的。

7、Bean的自动装配(autowire)

  • 自动装配是Spring满足bean依赖的一种方式!
  • Spring会在上下文中自寻找,并自动给bean装配属性!

在Spring中有三种装配的方式:

  1. 在xml中显示的配置。
  2. 在java中显示的配置。
  3. 隐式的自动装配bean。

7.1 byName自动装配 

  1. <!--byName:会自己在容器上下文中查找,和自己对象set方法后面的值对应的bean id!-->
  2. <bean id="people" class="com.lei.pojo.People" autowire="byName">
  3. <property name="name" value="张三啊"/>
  4. </bean>

7.2 byType自动装配

  1. <!--byName:会自己在容器上下文中查找,和自己对象属性类型相同的bean id!-->
  2. <bean id="people" class="com.lei.pojo.People" autowire="byType">
  3. <property name="name" value="张三啊"/>
  4. </bean>
  5. </bean>

小结:

byname的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致!

bytype的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致!

7.3 使用注解实现自动装配

步骤:

1、导入约束 xmlns:context="http://www.springframework.org/schema/context"

2、配置注解的支持 <context:annotation-config/>

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. <context:annotation-config/>
  5. </beans>

3、@Autowired 该注解写到属性上方即可!也可以写到Set方法上!

使用该注解,连Set方法也可以省略掉,前提是这个自动装配的属性在IOC容器中存在,且符合名字(byname)!

 扩展:

@Qualifier(value ="dog222"):指定一个装配的值。

如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个[@Autowired]完成的时候,我们可以使用@Qualifier(value="xxx")去配置@Autowired的使用,指定一个唯一的bean对象注入!

扩展注解:

该注解作用:当字段标记了这个注解,说明这个字段可以为null。

小结:

@Resource和@Autowired的区别:

  • 都是用来自动装配的,都可以放在属性字段上。
  • @Autowired注解由Spring提供,只byType注入。
  • @Resource默认通过byName的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下就会报错。

8、使用注解开发 

使用注解需要导入context约束,增加注解的支持。

  • 注解支持
    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <beans xmlns="http://www.springframework.org/schema/beans"
    3. xmlns:context="http://www.springframework.org/schema/context"
    4. <context:annotation-config/>
    5. </beans>

属性如何注入:

衍生的注解:

@Component有几个衍生的注解,我们在开发中,会按照mvc三层架构分层。

  • dao【@Repository
  • service怕【@Service
  • controller【@Controller

这四个注解功能都是一样的,都是代表将某个类注册到spring中,装配Bean。

作用域:

可设置单例模式或原型模式,在类上面设置。

@Scope("prototype")

小结:

xml与注解:

  • xml更加万能,适用与任何场合!维护简单。
  • 注解不是自己的类使用不了,维护相对复杂!

xml与注解最佳实践:

  • xml用来管理bean。
  • 注解只负责完成属性的注入。
  • 我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持。
  1. <!--指定要扫描的包,这个包下的注解就会生效-->
  2. <context:component-scan base-package="com.lei"/>
  3. <context:annotation-config/>

9、使用JavaConfig实现配置

Basic Concepts: @Bean and @Configuration 注解

 测试:

10、代理模式

什么是代理模式?代理模式就是Spring和SpringMVC的底层。

分为:静态代理与动态代理。

静态代理模式:

生活中的概念比如:房东和中介都有一个共同的目标,那就是出租房,房东找到中介租房,房东只有一件事就是租出房子,中介可以写很多业务给客户实现需要的业务,最后通过代理模式去实现。

角色分析:

  • 抽象角色:一般会使用接口或者抽象类来解决
  • 真实角色:被代理的角色
  • 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作
  • 客户:访问代理对象的人!

抽象代码解释: 

1.接口

  1. public interface Rent {
  2. public void rent();
  3. }

2. 真实角色

  1. public class Host implements Rent {
  2. @Override
  3. public void rent() {
  4. System.out.println("我要出租房子!");
  5. }
  6. }

3. 代理角色

  1. public class Client implements Rent {
  2. private Host host;
  3. @Override
  4. public void rent() {
  5. }
  6. public Client() {
  7. }
  8. public Client(Host host) {
  9. this.host = host;
  10. host.rent();
  11. dao();
  12. }
  13. public void dao(){
  14. System.out.println("带房客看房!");
  15. System.out.println("收中介费!");
  16. }
  17. }

4. 客户端访问代理角色

  1. public class Proxy {
  2. public static void main(String[] args) {
  3. Host host = new Host();
  4. Client client = new Client(host);
  5. }
  6. }

代理模式的好处:

  • 可以使真实角色的操作更加纯粹,不用去关注一些公共的业务。
  • 公共业务也就交给代理角色,实现了业务的分工。
  • 公共业务发生扩展的时候,方便集中管理!

缺点:

  • 一个真实角色就会产生一个代理角色。代码量就会翻倍,开发效率会变低。

加深理解: 

我们使用mvc架构开发时,我们可以称之为纵向开发。

在开发的时候,我们不可能去改变公司原有的代码,我们只能通过AOP的实现机制去添加一些功能。

总的说,代理模式就是让我们通过mvc架构,再去在深一层的去添加了一些实现功能。

动态代理模式:

动态代理简而言之就是,在不改变原有类的基础上,扩展自己的其他代码。

  • 动态代理和静态代理角色一样。
  • 动态代理的代理类是动态生成的,不是我们直接写好的。
  • 动态代理分为两大类:基于接口的动态代理,基于类的动态代理。

动态代理的好处:

  • 可以使真实角色的操作更加纯粹,不用去关注一些公共的业务。
  • 公共业务也就交给代理角色,实现了业务的分工。
  • 公共业务发生扩展的时候,方便集中管理!
  • 一个动态代理类的是一个接口,一般就是对应的一类业务。
  • 一个动态代理类可以代理多个类,只要是实现了同一个接口即可。

11、AOP

11.1 什么是AOP

在软件业,AOP为(Aspect Oriented Programming)的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

AOP就是为了解耦而生的。

概念:AOP是思想是这样的,他是基于动态代理的,我们将需要注入的切面进行代理,当我们想要使用的时候,就将公共逻辑添加进去,而不需要修改原有的业务逻辑代码,只需要在原来的业务逻辑上做一些增强功能即可。

11.2 AOP在Spring中的作用

提供声明事务:允许用户自定义切面

  • 横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点,如日志,安全,缓存,事务等等....
  • Aspect:关注点模块化,这个关注点可能会横切多个对象。(schema-based approach或在普通类中加入@Aspect注解来实现)
  • Advice:可以理解为通知建议,在spring中通过定义Advice来定义代理逻辑。
  • pointcut:是切点,表示Advice对应代理逻辑应用在哪个类,哪个方法上。
  • Advisor:等于Advice+pointcut,表示代理逻辑和切面的一个整体,程序员可以通过定义或封装一个Advisor,来定义切点和代理逻辑。
  • Weaving:表示织入,将Advice代理逻辑在源代码级别嵌入到切点的过程就叫做织入。
  • Target:表示目标对象,也就是被代理的对象,在AOP生成代理对象中会持有目标对象。
  • Join Point:表示连接点,在springAOP中,就是方法的执行点。

 SpringAOP中,通过Advice定义横切逻辑,Spring中支持5种类型的Advice。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/796448
推荐阅读
相关标签
  

闽ICP备14008679号