Spring是什么
Spring是一个轻量级控制反转(IOC)和面向切面(AOP)的容器框架。
Spring组成
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j8QPlQIq-1638718924065)(spring.assets/format,png.png)]
-
Spring Boot
- 一个快速开发的脚手架
- 可以快速开发单个微服务
- 学习SpringBoot前提Spring + SpringMVC
-
Spring Cloud
- springCloud基于SpringBoot实现的
SpringBoot
SringCloud
环境
1、导包
2、
IOC 控制反转原理
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IOC容器,其实现方法是依赖注入。实现了(创建+配置)与组件的使用分离。
Spring原理
Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建于组织对象存入容器中,程序使用时再从IOC容器中取出需要的对象。
采取XML方式配置Bean时,Bean的定义信息和实现分离的。而采取注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
XML配置通过set注入
通过getBean获取的时候,使用无参构造创建对象。应该是指针指向已经被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">
<!--使用Spring来创建的对象,在Spring中都称为Bean-->
<!-- id Bean的唯一标识符号相当于名字,class创建的类名-->
<bean id="hello" class="spring.Hello">
<!-- name类的变量名,value变量的值-->
<property name="str" value="spring"/>
</bean>
</beans>
package spring;
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.getStr());
}
}
package spring;
public class Hello {
private String str;
public Hello() {
}
public Hello(String str) {
this.str = str;
}
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
@Override
public String toString() {
return "Hello{" +
"str='" + str + '\'' +
'}';
}
}
其它
<bean id="mysqlImpl" class="zui.dao.UserDaoMysqlImpl"/>
<bean id="UserServerImpl" class="zui.server.UserServerImpl">
<!--ref引用Spring容器中创建好的对象-->
<property name="userDao" ref="mysqlImpl"/>
</bean>
IOC创建对象的方式
-
默认无参构造
-
使用有参构造方法
-
下标赋值
<bean id="UserServerImpl" class="zui.server.UserServerImpl"> <!--ref引用Spring容器中创建号的对象--> <constructor-arg index="0" ref="mysqlImpl"/> </bean>
-
参数的类型匹配,如果多个相同类型就有问题,不建议使用
<bean id="UserServerImpl" class="zui.server.UserServerImpl"> <!--ref引用Spring容器中创建号的对象--> <constructor-arg type="zui.dao.MysqlImpl" ref="mysqlImpl"/> </bean>
-
直接通过参数名来设置
<bean id="UserServerImpl" class="zui.server.UserServerImpl"> <!--ref引用Spring容器中创建号的对象--> <constructor-arg name="MysqlImpl" ref="mysqlImpl"/> </bean>
-
Spring配置
别名
<bean id="UserServerImpl" class="zui.server.UserServerImpl">
<constructor-arg name="MysqlImpl" ref="mysqlImpl"/>
</bean>
<!--name要取别名的Bean的名字,可通过别名获取对象-->
<alias name="UserServerImpl" alias="biemign"/>
Bean配置
<!--
id:Bean的唯一标识符号相当于名字;
class:Bean对象对应的全限定名:包名 + 类型
name:也是别名
-->
<bean id="UserServerImpl" class="zui.server.UserServerImpl" name="bieming bieming2">
<constructor-arg name="MysqlImpl" ref="mysqlImpl"/>
</bean>
import
这个一般用于团队开发,他可以将多个配置文件,导入合并为一个applicationContext.xml
<import resource="bean.xml"/>
DI依赖注入
构造器注入
有参构造注入
Set注入
无参构造Set注入
Student类{
private String name; // 字符串
private Addrress address; // 类
private String[] books; // 数组
private List<String> hobbys;
private Map<String,String> card;
private Set<String> games;
private String wife; // 空指针null
private Properties info; // 配置类
}
<bean id="address" class="zui.Address"/>
<bean id="student" class="zui.Student">
<property name="name" value="字符串"/>
<property name="address" ref="address"/>
<property name="books">
<array>
<value>数组值1</value>
<value>数组值2</value>
</array>
</property>
<property name="hobbys">
<list>
<value>列表值1</value>
<value>列表值</value>
</list>
</property>
<property name="card">
<map>
<entry key="" value=""/>
<entry key="" value=""/>
</map>
</property>
<property name="games">
<set>
<value></value>
<value></value>
</set>
</property>
<property name="wife">
<null/>
</property>
<property name="info">
<props>
<prop key="">213</prop>
<prop key="">男</prop>
<prop key="username">root</prop>
</props>
</property>
</bean>
扩展注入
p命名空间注入,本质Set注入;
c命名空间注入,本质构造器注入;
需要导入第三方约束:xmlns:p="“或者xmlns:c=”"
Bean作用域
1.单例模式(Spring默认机制),get的时候,取的都是同一个对象。
<bean id="classone" class="zui.ClassOne" scope="singleton"/>
2.原型模式:每次从容器中get的时候,都会产生一个新的对象!
<bean id="classone" class="zui.ClassOne" scope="prototype"/>
3.其余
request、session、application、websocket四种模式只在web开发中使用。
Bean的自动装配
- 自动装配是Spring满足bean依赖一种方式!
- Spring会在上下文中自动寻找,并自动给bean装配属性!
spring中的三种装配方式
1.在xml中显示的配置
2.在java中显示配置
3.隐式的自动装配bean【重要】
autowire自动装配
<bean id="cat" class="zui.Cat"/>
<bean id="dog" class="zui.Dog"/>
<bean id="people" class="zui.People" autowire="byName">
</bean>
<!--
byName:会自动在容器上下文中查找,和自己对象set方法的值对应的beanid;
byType:会自动在容器上下文查找,和自己对象属性类型相同的bean;
--!>
<!--
例子自动装配People类中cat、dog变量。
--!>
使用注解实现自动装配
spring大部分使用注解装配
环境:
1、导入约束:xmlns:contest=""
2、配置注解的支持(开启):context:annotation-config/
- 前提:自动装配的属性中Spring容器中存在,切名字符合byType。
public class People{
@Autowied
pivate Dog dog;
@Autowied
@Qualifie(value="cat1") // 有多个参数,不符合byType时指定name;
pivate Cat cat;
}
java原生注解@Resource相当于先byName再byType.
public class People{
@Resource
private Dog dog;
@Resource(name="cat1")
private Cat cat;
}
使用注解开发入门
使用注解必须保证导入aop的包;
使用注解需要导入context约束,增加注解的支持;
1.@compoent注解组装bean和注入值
<!--
指定注解要扫描的包,这个包下的注解就会生效
--!>
<context:component-scan base-package="zui.pojo">
<!--开启注解支持--!>
<cintext:annotation-config/>
import org.springframework.stereotype.Component;
@Component // 组装Bean
public class User{
@Value("注入的值") // 注入值
public String name;
}
2.衍生的注解
- @Component有几个衍生注解,我们在web开发中,会按照mvc三层架构分层;
- dao:@Repository
- service:@Service
- controller:Controller
这四个注解功能都是一样的,代表将某个类注册到Spring中,装配Bean;
3.自动装配注解
4.作用域注解
@Scope("singleton") // 单例模式
@Scope("prototype") // 原型模式
5.总结
xml与注解
- xml:更加万能,适用于任何场合,维护简单方便
- 注解:不是自己类使用不来,维护相对复杂
最佳实践:
- xml用来管理bean;
- 注解只负责属性的注入;
完全使用Java的方式配置Spring
我们现在要完全不使用Spring的xml配置,全权交给Java来做;
JavaConfig时Spring的一个子项目,在Spring4之后,它成为了一个核心功能;
实体类
@Component
public class User{
@Value("注入值")
public String name;
public String getName(){
return name;
}
public void setName(String name){
this.name;
}
@Override
public String toString(){
return "User"{" +
"name='" + name + '\'' +'}';
}
}
配置类
// @ComponentScan("com.zui.pojo") 显示扫描;
@Import("com.zui.Config2") // 讲两个配置类引成一个类
@Configuration // 被Spring托管,注册到容器中,它本身就是一个@component;将相当于xml中的扫描;
public class Config{
// 注册Bean
// 方法名:相当于bean标签的id属性;
// 返回值:相当于bean标签的class属性;
@Bean
public User getUser(){
return new User();
}
}
如果完全通过注解配置类方法使用Spring,就只能使用AnnotationConfigApplicationContest()上下文来获取容器,通过配置类的class对象加载!
实体类
public class MyTest{
public static void main(String[] args){
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class); // 填配置类
User getUser = (User) context.getBean("getUser");
System.out.println(getUser.getName());
}
}