1.Spring简介
Spring框架是 Java 平台的一个开源的全栈应用程序框架和控制反转容器实现,一般被直接称为Spring。该框架的一些核心功能理论上可用于任何Java 应用,但 Spring 还为基于Java企业版平台构建的Web 应用提供了大量的拓展支持。
官网:www.spring.io
Maven配置:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.19.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.19.RELEASE</version>
</dependency>
1.2 优点
- Spring是一个开源的免费的框架(容器)!
- Spring是一个轻量级的、非入侵式的框架!
- 控制反转(IOC),面向切面编程(AOP)!
- 支持事务的处理,对框架整合的支持!
总结一句话:Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架!
1.3组成
2.IOC思想
控制反转IOC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IOC的一种方法,也有人认为DI只是IOC的另一种说法。没有IOC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。
采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。
IoC 也称为依赖注入 (DI)。这是一个过程,对象仅通过构造函数参数、工厂方法的参数或在对象实例被构造或从工厂方法返回后设置的属性来定义它们的依赖关系(即与它们一起工作的其他对象) . 然后容器在创建 bean 时注入这些依赖项。这个过程基本上是 bean 本身通过使用类的直接构造或诸如服务定位器模式之类的机制来控制其依赖关系的实例化或位置的逆过程(因此称为控制反转)。
该org.springframework.context.ApplicationContext
接口代表 Spring IoC 容器,负责实例化、配置和组装 bean。容器通过读取配置元数据来获取关于要实例化、配置和组装哪些对象的指令。配置元数据以 XML、Java 注释或 Java 代码表示。它允许您表达组成应用程序的对象以及这些对象之间丰富的相互依赖关系。
ApplicationContext
Spring 提供了该接口的几个实现。在独立应用程序中,通常会创建 ClassPathXmlApplicationContext
或的实例FileSystemXmlApplicationContext
。虽然 XML 一直是定义配置元数据的传统格式,但您可以通过提供少量 XML 配置来以声明方式支持这些附加元数据格式,从而指示容器使用 Java 注释或代码作为元数据格式。
3.IOC创建对象的方式
-
无参构造函数,默认实现
-
想要使用有参构造函数三种实现方式
1.使用下标索引创建
<bean id="user" class="com.wyz.bean.User">
<constructor-arg index="0" value="无涯子"/>
</bean>
2.使用类型来创建(不推荐)
<bean id="user" class="com.wyz.bean.User">
<constructor-arg type="java.lang.String" value="无涯子1"/>
</bean>
3.使用参数名字来创建
<bean id="user" class="com.wyz.bean.User">
<constructor-arg name="name" value="wuyazi"/>
</bean>
默认情况下只会创建一个对象,每次获取都是同一个对象。
总结:在配置文件加载的时候,容器中管理的对象就已经开始初始化了
4.Spring配置
1.alias别名
<alias name="user" alias="userNew"/>
2.bean
<bean id="UserService" class="com.wyz.service.UserServiceImpl">
<property name="userDao" ref="Dao"/>
</bean>
/*
id:唯一标识
class:要加载的对象的路径,包.类
*/
3.import导入
可以把其他配置文件导入到当前文件中,一般用于团队协作开发
<import resource="bean.xml"/>
5.DI依赖注入
通过构造器注入
<bean id="user" class="com.wyz.bean.User">
<constructor-arg index="0" value="无涯子"/>
</bean>
<bean id="user" class="com.wyz.bean.User">
<constructor-arg type="java.lang.String" value="无涯子1"/>
</bean>
<bean id="user" class="com.wyz.bean.User">
<constructor-arg name="name" value="wuyazi"/>
</bean>
通过set方式注入(重点)
创建一个对象环境
public class Address {
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Address{" +
"address='" + address + '\'' +
'}';
}
}
public class Student {
private String name;
private Address address;
private String[] books;
private List<String> hobby;
private Map<String,Object> carts;
private Properties info;
private String wife;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String[] getBooks() {
return books;
}
public void setBooks(String[] books) {
this.books = books;
}
public List<String> getHobby() {
return hobby;
}
public void setHobby(List<String> hobby) {
this.hobby = hobby;
}
public Map<String, Object> getCarts() {
return carts;
}
public void setCarts(Map<String, Object> carts) {
this.carts = carts;
}
public Properties getInfo() {
return info;
}
public void setInfo(Properties info) {
this.info = info;
}
public String getWife() {
return wife;
}
public void setWife(String wife) {
this.wife = wife;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", address=" + address +
", books=" + Arrays.toString(books) +
", hobby=" + hobby +
", carts=" + carts +
", info=" + info +
", wife='" + wife + '\'' +
'}';
}
}
配置文件进行注入
<bean id="address" class="com.wyz.bean.Address">
<property name="address" value="武汉"/>
</bean>
<bean id="student" class="com.wyz.bean.Student">
<!-- 普通属性注入-->
<property name="name" value="无涯子"/>
<!-- 对象注入-->
<property name="address" ref="address"/>
<!-- 数组注入-->
<property name="books">
<array>
<value>西游记</value>
<value>红楼梦</value>
<value>三国演义</value>
</array>
</property>
<!-- list注入-->
<property name="hobby">
<list>
<value>跑步</value>
<value>LOL</value>
</list>
</property>
<!-- map注入-->
<property name="carts">
<map>
<entry key="身份证" value="4556677"/>
<entry key="学生证" value="1234"/>
</map>
</property>
<!-- properties注入-->
<property name="info">
<props>
<prop key="no">111111</prop>
<prop key="sex">man</prop>
</props>
</property>
<property name="wife">
<null/>
</property>
</bean>
测试文件
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
Student student = (Student) context.getBean("student");
System.out.println(student);
通过其他方式注入
P命名空间和c命名空间
Bean的作用域
默认情况下是singleton单例。
5.Bean的自动装配
在Spring中有三种装配方式
- 在xml文件中显示配置
- 在java中显示配置
- 隐式的自动装配bean(重要)
byName:会自动在容器上下文寻找和自己对象set方法后面的值对应的beanid.
byType:会在容器上下文寻找和自己对象属性相同的类型的bean
byName装配
<bean id="cat" class="com.wyz.pojo.Cat"/>
<bean id="dog" class="com.wyz.pojo.Dog"/>
<bean id="person" class="com.wyz.pojo.Person" autowire="byName">
<property name="name" value="无涯子"/>
</bean>
byType装配
<bean id="cat" class="com.wyz.pojo.Cat"/>
<bean id="dog1111" class="com.wyz.pojo.Dog"/>
<bean id="person" class="com.wyz.pojo.Person" autowire="byType">
<property name="name" value="无涯子"/>
</bean>
自动装配
1.导入xml配置文件
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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
@Autowired进行自动装配
这个注解可以设置到属性上面或者set方法上面。当设置到属性上面的时候,对应的属性可以没有set方法也可以进行注入。当有多个相同的对象的时候,自动注入可以无法确定注入哪一个,可以使用@Qualifier(value = "")确定注入具体哪一个。
private String name;
@Autowired
@Qualifier(value = "cat1")
private Cat cat;
@Autowired
private Dog dog;
@Resource JDK原生注解
@Resource
private Cat cat;
@Resource
private Dog dog;
@Resource(name = "cat1")
private Cat cat;
@Resource(name = "dog2")
private Dog dog;
@Autowired和@Resource区别
两者都是用来实现自动装配的注解
@Autowired是通过byType来实现自动装配,可以有多个相同类型的对象,可以通过@Qualifier注解来进行唯一区别
@Resource是先通过名字来实现装配,装配不成功就通过类型进行装配,如果继续装配不成功就报错
二者选择执行顺序不同
6.使用注解开发
配置环境:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解支持-->
<context:annotation-config/>
<!-- 指定注解扫描的目录-->
<context:component-scan base-package="com.wyz"/>
</beans>
-
注册bean 使用@Component注解
@Component public class User { public String name = "wyz"; }
-
注入属性 @Value()
@Component public class User { @Value("无涯子") public String name; }
-
衍生注解 MVC开发模式中使用@Repository注册dao层,使用@Service注册到Service层 使用@Controller注册Controller层
@Service public class UserService { } @Repository public class UserDao { } @Controller public class UserController { }
-
作用域使用@Scope注解
-
小结
xml是万能的,在任何场景都使用
注解不是自己的类使用不了,相对复杂
二者结合起来使用效果会更好
7.使用Java方式配置Spring
完全使用Java来配置Spring,不需要配置文件,一个JavaConfig配置文件就是一个xml文件
@Configuration//相当于一个xml配置文件
public class TestConfig {
@Bean//相当于在xml配置文件中注册一个bean,注册的id就是getPerson,返回的类型就是Person
public Person getPerson(){
return new Person();
}
}
@Component
public class Person {
@Value("wyzTest")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}