赞
踩
目录
官网:
使用Spring前事先导入需要的jar包:
- <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>5.3.14</version>
- </dependency>
Spring是一个开源的免费的框架(容器思想),同时它也是一个生态!
Spring是一个轻量级,非入侵式的框架!
控制反转(IOC),面向切面编程(AOP)!
支持事务的处理,对框架整合的支持!
Spring的开放性,并不强制应用完全依赖于Spring,开发者可以自由选择Spring的部分或全部!
总的一句话Spring就是一个轻量级控制反转(IOC),和面向切面编程(AOP)的框架。
在Spring的官网有这样个介绍:现代化的Java开发!(就是基于Spring的开发)
Spring Boot 介绍:
Spring Cloud介绍:
为什么要学习Spring?
因为现在大多数的公司都在使用Spring Boot进行快速开发,学习Spring Boot的前提,则需要完全掌握Spring 及SpringMVC!相当于承上启下的作用!
弊端:发展了太久之后,违背了原来的理念!配置十分繁琐,人称:"配置地狱"!
通过我们原来的MVC结构实现:
之前的结构:
我们当时进行这些Dao层的调用比较复杂,都是通过用户的需求,然后我们程序员在进行业务层的修改。
控制权在我们程序员手上。
这样的修改成本十分的昂贵。为什么呢?因为一旦代码量多了,那么我们程序员修改成本就会变得很高。
现在有一个思想上的革命:
我们使用一个Set接口实现:
- // 利用set进行动态实现值的注入
- public void setDaoUser(DaoUser daoUser) {
- this.daoUser = daoUser;
- }
这时候控制权会在用户手上。
之前,程序是主动创建对象!控制权在程序员手上!
使用set注入后,程序不在具有主动性,而是变成了被动的接收对象!
这种思想,从本质上解决了问题,我们程序员不用再去管理对象的创建了。系统的耦合性大大降低,我们可以更加专注的在业务的实现上!
控制反转IOC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IOC的一种方法,也有人认为DI只是IOC的另一种说法。没有IOC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。
我们采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
什么是控制反转?
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的IOC容器。其实现方法是依赖注入(Dependency injection ,DI)。
这个过程就叫做控制反转:
控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用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 = 传递的参数
- <?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">
-
- <bean id="hello" class="com.lei.pojo.Hello">
- <property name="str" value="Spring"/>
- </bean>
-
- </beans>
3、测试
- public static void main(String[] args) {
- // 获取spring上下文对象
- ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
- // 通过context获取bean容器,提示:在这里使用哪个bean就需要强转该bean的类型
- Hello hello = (Hello)context.getBean("hello");
- // 输出hello.toString()方法。对应xml中给str设置的值
- System.out.println(hello.toString());
- }
输出结果:
4、扩展
ref是代表,我要使用哪个bean就把哪个bean的id名放到ref中,供bean调用。
- <bean id="userImplDao" class="com.lei.pojo.Hello">
- <property name="daoUser" ref="userImplDao"></property>
- </bean>
方式一:使用无参构造创建对象,默认的!
方式二:假设我们要使用有参构造创建对象。
三种方式:
- <!--
- 第一种,下标赋值
- -->
- <bean id="user" class="com.lei.pojo.User">
- <constructor-arg index="0" value="张三"/>
- </bean>
-
- <!--第二种方式,通过类型创建,不建议使用,因为如果参数是两个String类型的就不可使用了-->
- <bean id="user" class="com.lei.pojo.User">
- <constructor-arg type="java.lang.String" value="李四"/>
- </bean>
-
- <!--第三中方式,通过参数名来设置-->
- <bean id="user" class="com.lei.pojo.User">
- <constructor-arg name="name" value="赵五"/>
- </bean>
总结:在配置文件加载的时候,容器中管理的对象就已经被初始化了。
提示:别名,如果配置了别名,我们也可以通过别名来获取到对象。
<alias name="user" alias="newUser"/>
id:bean的唯一标识符,也就是相当于我们学的对象名。
class:bean对象所对应的全限定名:包名+类型。
name:也是别名,而且name可以同时取多个别名。
- <bean id="userT" class ="com.lei.pojo.userT" name="user2 u2,u3;u4">
- <property name="name" value="张三"/>
- </bean>
import,一般用于团队开发使用,他可以将多个配置文件,导入合并为一个。
假设,现在项目中有多个人开发,这三个人负责不同的类开发,不同的类需要注册在不同的bean中,我们可以利用import将所有人的beans.xml合并为一个总的!
- <import resource="beans.xml">
- <import resource="beans2.xml">
- <import resource="beans3.xml">
使用的时候,直接使用总的配置就可以了。
利用构造函数为对象中的属性注入值,需要在xml配置文件中进行手动的配置。
Set注入指的就是在接受注入的类中定义一个要被注入的类型的一个set方法,并在参数中定义需要注入的元素。
6.2.1 搭建环境
复杂类型注入:
1、创建实体类 Address
- package com.lei.pojo;
-
- public class Address {
- private String address;
- // get.set方法
- }
2 、创建实体类 Student
- import java.util.*;
-
- public class Student {
- private String name;
- private Address address;
- private String[] books;
- private List<String> hobbys;
- private Map<String,String> card;
- private Set<String> games;
- private String wifi;
- private Properties info;
-
- }// get、set、toString方法
3、创建bean.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">
-
- <bean id="student" class="com.lei.pojo.Student">
- <!--第一种,使用普通方法注入-->
- <property name="name" value="张三"/>
- </bean>
-
- </beans>
4、测试类
- public class MyTest {
- public static void main(String[] args) {
-
- ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
- Student student = (Student)context.getBean("student");
- System.out.println(student.toString());
-
- }
- }
6.2.2 复杂类型注入
- <?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">
-
-
-
- <bean id="address" class="com.lei.pojo.Address">
- <property name="address" value="中国"/>
- </bean>
- <bean id="student" class="com.lei.pojo.Student">
- <!--第一种,使用普通方法注入-->
- <property name="name" value="张三"/>
- <!--第二种,Bean注入:ref-->
- <property name="address" ref="address"/>
- <!--数组-->
- <property name="books">
- <array>
- <value>法律听讲</value>
- <value>哈佛听讲</value>
- <value>津大听讲</value>
- </array>
- </property>
- <!--list-->
- <property name="hobbys">
- <list>
- <value>听音乐</value>
- <value>打篮球</value>
- <value>唱歌</value>
- </list>
- </property>
- <!--Map-->
- <property name="card">
- <map>
- <entry key="身份证" value="111111222222223333"></entry>
- <entry key="ID卡" value="123123123"></entry>
- </map>
- </property>
- <!--Set-->
- <property name="games">
- <set>
- <value>lol</value>
- <value>bob</value>
- <value>coc</value>
- </set>
- </property>
- <!--wifi-->
- <property name="wifi">
- <null/>
- </property>
- <!--props-->
- <property name="info">
- <props>
- <prop key="name">张三</prop>
- <prop key="id">12311</prop>
- <prop key="pwd">123456</prop>
- </props>
- </property>
-
- </bean>
-
-
-
- </beans>
注入结果
我们可以通过p命名空间和c命名空间进行注入:
- <bean id="user" class="com.lei.pojo.User" p:age="18" p:name="张三"/>
- <bean id="user2" class="com.lei.pojo.User" c:age="20" c:name="李四"/>
注意点:在使用p命名空间和c命名空间的时候要添加约束名!
添加到beans里面:
- xmlns:p="http://www.springframework.org/schema/p"
- xmlns:c="http://www.springframework.org/schema/c"
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开发中使用的。
在Spring中有三种装配的方式:
- <!--byName:会自己在容器上下文中查找,和自己对象set方法后面的值对应的bean id!-->
- <bean id="people" class="com.lei.pojo.People" autowire="byName">
- <property name="name" value="张三啊"/>
- </bean>
- <!--byName:会自己在容器上下文中查找,和自己对象属性类型相同的bean id!-->
- <bean id="people" class="com.lei.pojo.People" autowire="byType">
- <property name="name" value="张三啊"/>
- </bean>
- </bean>
小结:
byname的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致!
bytype的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致!
步骤:
1、导入约束 xmlns:context="http://www.springframework.org/schema/context"
2、配置注解的支持 <context:annotation-config/>
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:context="http://www.springframework.org/schema/context"
-
- <context:annotation-config/>
-
- </beans>
3、@Autowired
该注解写到属性上方即可!也可以写到Set方法上!
使用该注解,连Set方法也可以省略掉,前提是这个自动装配的属性在IOC容器中存在,且符合名字(byname)!
扩展:
@Qualifier(value ="dog222")
:指定一个装配的值。
如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个[@Autowired]完成的时候,我们可以使用@Qualifier(value="xxx")去配置@Autowired的使用,指定一个唯一的bean对象注入!
扩展注解:
该注解作用:当字段标记了这个注解,说明这个字段可以为null。
小结:
@Resource和@Autowired的区别:
使用注解需要导入context约束,增加注解的支持。
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:context="http://www.springframework.org/schema/context"
-
- <context:annotation-config/>
-
- </beans>
@Component
有几个衍生的注解,我们在开发中,会按照mvc三层架构分层。
@Repository
】@Service
】@Controller
】这四个注解功能都是一样的,都是代表将某个类注册到spring中,装配Bean。
可设置单例模式或原型模式,在类上面设置。
@Scope("prototype")
小结:
xml与注解:
xml与注解最佳实践:
- <!--指定要扫描的包,这个包下的注解就会生效-->
- <context:component-scan base-package="com.lei"/>
- <context:annotation-config/>
Basic Concepts: @Bean
and @Configuration
注解
测试:
什么是代理模式?代理模式就是Spring和SpringMVC的底层。
分为:静态代理与动态代理。
生活中的概念比如:房东和中介都有一个共同的目标,那就是出租房,房东找到中介租房,房东只有一件事就是租出房子,中介可以写很多业务给客户实现需要的业务,最后通过代理模式去实现。
角色分析:
抽象代码解释:
1.接口
- public interface Rent {
- public void rent();
- }
2. 真实角色
- public class Host implements Rent {
- @Override
- public void rent() {
- System.out.println("我要出租房子!");
- }
- }
3. 代理角色
- public class Client implements Rent {
-
- private Host host;
- @Override
- public void rent() {
- }
- public Client() {
- }
- public Client(Host host) {
- this.host = host;
- host.rent();
- dao();
-
- }
- public void dao(){
- System.out.println("带房客看房!");
- System.out.println("收中介费!");
- }
- }
4. 客户端访问代理角色
- public class Proxy {
- public static void main(String[] args) {
- Host host = new Host();
- Client client = new Client(host);
- }
- }
代理模式的好处:
缺点:
加深理解:
我们使用mvc架构开发时,我们可以称之为纵向开发。
在开发的时候,我们不可能去改变公司原有的代码,我们只能通过AOP的实现机制去添加一些功能。
总的说,代理模式就是让我们通过mvc架构,再去在深一层的去添加了一些实现功能。
动态代理简而言之就是,在不改变原有类的基础上,扩展自己的其他代码。
动态代理的好处:
在软件业,AOP为(Aspect Oriented Programming)的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
AOP就是为了解耦而生的。
概念:AOP是思想是这样的,他是基于动态代理的,我们将需要注入的切面进行代理,当我们想要使用的时候,就将公共逻辑添加进去,而不需要修改原有的业务逻辑代码,只需要在原来的业务逻辑上做一些增强功能即可。
提供声明事务:允许用户自定义切面
SpringAOP中,通过Advice定义横切逻辑,Spring中支持5种类型的Advice。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。