|
@@ -0,0 +1,921 @@
|
|
|
+> [TOC]
|
|
|
+
|
|
|
+# 1、Spring
|
|
|
+
|
|
|
+***
|
|
|
+
|
|
|
+## 1.1、简介
|
|
|
+
|
|
|
+- Spring:春天------>给软件行业带来了春天!
|
|
|
+
|
|
|
+- 2002,首次推出了Spring框架的雏形:interface21框架!
|
|
|
+
|
|
|
+- Spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于2004年3月24日发布了1.0正式版。
|
|
|
+
|
|
|
+- **Rod Johnson**,Spring Framework创始人,著名作者。很难想象Rod Johnson的学历,真的让好多人大吃一惊,他是悉尼大学的博士,然而他的专业不是计算机,而是音乐学。
|
|
|
+
|
|
|
+- Spring理念:使现有的技术更加容易使用,本身是一个大杂烩,整合了现有的技术框架!
|
|
|
+
|
|
|
+- SSH:Struct2 + Spring + Hibernate!
|
|
|
+
|
|
|
+- SSM:SpringMVC + Spring + Mybatis!
|
|
|
+
|
|
|
+官网:https://spring.io/projects/spring-framework#overview
|
|
|
+
|
|
|
+官方下载地址:https://repo.spring.io/release/org/springframework/spring/
|
|
|
+
|
|
|
+GitHub:https://github.com/spring-projects/spring-framework
|
|
|
+
|
|
|
+```xml
|
|
|
+ <dependency>
|
|
|
+ <groupId>org.springframework</groupId>
|
|
|
+ <artifactId>spring-webmvc</artifactId>
|
|
|
+ <version>5.3.8</version>
|
|
|
+ </dependency>
|
|
|
+ <dependency>
|
|
|
+ <groupId>org.springframework</groupId>
|
|
|
+ <artifactId>spring-jdbc</artifactId>
|
|
|
+ <version>5.3.8</version>
|
|
|
+ </dependency>
|
|
|
+```
|
|
|
+
|
|
|
+## 1.2 优点
|
|
|
+
|
|
|
+- Spring是一个开源的免费的框架(容器)!
|
|
|
+- Spring是一个轻量级的、非入侵式的框架!
|
|
|
+- 控制反转(IOC),面向切面编程(AOP)!
|
|
|
+- 支持事务的处理,对框架整合的支持!
|
|
|
+
|
|
|
+**总结一句话:Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架!**
|
|
|
+
|
|
|
+## 1.3、组成
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+## 1.4 拓展
|
|
|
+
|
|
|
+现代化的Java开发!说白了就是基于Spring的开发!
|
|
|
+
|
|
|
+- Spring Boot
|
|
|
+ - 一个快速开发的脚手架
|
|
|
+ - 基于SpringBoot可以快速的开发单个微服务
|
|
|
+ - 约定大于配置
|
|
|
+- Spring Cloud
|
|
|
+ - SpringCloud是基于SpringBoot实现的
|
|
|
+
|
|
|
+因为现在大多数公司都在使用SpringBoot进行快速开发,学习SpringBoot的前提,需要完全掌握Spring以及SpringMVC!**承上启下的作用!**
|
|
|
+
|
|
|
+**弊端:发展了太久之后,违背了原来的理念!配置十分繁琐,人称:“配置地狱”**
|
|
|
+
|
|
|
+# 2、IOC理论推导
|
|
|
+
|
|
|
+***
|
|
|
+
|
|
|
+1. UserDao 接口
|
|
|
+
|
|
|
+ ```java
|
|
|
+ public interface UserDao {
|
|
|
+ void getUser();
|
|
|
+ }
|
|
|
+ ```
|
|
|
+
|
|
|
+2. UserDaoImpl 实现类
|
|
|
+
|
|
|
+ ```java
|
|
|
+ public class UserDaoImpl implements UserDao {
|
|
|
+ public void getUser() {
|
|
|
+ System.out.println("默认获取用户数据");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ```
|
|
|
+
|
|
|
+3. UserService 业务接口
|
|
|
+
|
|
|
+ ```java
|
|
|
+ public interface UserService {
|
|
|
+ void getUser();
|
|
|
+ }
|
|
|
+ ```
|
|
|
+
|
|
|
+4. UserServiceImpl 业务实现类
|
|
|
+
|
|
|
+ ```java
|
|
|
+ public class UserServiceImpl implements UserService {
|
|
|
+
|
|
|
+ private UserDao userDao = new UserDaoImpl();
|
|
|
+
|
|
|
+ public void getUser() {
|
|
|
+ userDao.getUser();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ```
|
|
|
+
|
|
|
+5. 测试
|
|
|
+
|
|
|
+ ```java
|
|
|
+ public class MyTest {
|
|
|
+ public static void main(String[] args) {
|
|
|
+
|
|
|
+ //用户实际调用的是业务层,dao层他们不需要接触!
|
|
|
+ UserService userService = new UserServiceImpl();
|
|
|
+ userService.getUser();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ```
|
|
|
+
|
|
|
+在我们之前的业务中,用户的需求可能会影响我们原来的代码,我们需要根据用户的需求去修改原代码!如果程序代码量十分大,修改一次的成本代价十分昂贵!
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+我们使用一个Set接口实现,已经发生了革命性的变化!
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+```java
|
|
|
+ private UserDao userDao;
|
|
|
+
|
|
|
+ // 利用set进行动态实现值的注入!
|
|
|
+ public void setUserDao(UserDao userDao) {
|
|
|
+ this.userDao = userDao;
|
|
|
+ }
|
|
|
+```
|
|
|
+
|
|
|
+- 之前,程序是主动创建对象!控制权在程序员手上!
|
|
|
+- 使用了set注入后,程序不再具有主动性,而是变成了被动的接收对象!
|
|
|
+
|
|
|
+这种思想,从本质上解决了问题,我们程序猿不用再去管理对象的创建了。系统的耦合性大大降低~,可以更加专注的在业务的实现上!这是IOC的原型!
|
|
|
+
|
|
|
+**IOC本质**
|
|
|
+
|
|
|
+**控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,**也有人认为DI只是IoC的另一种说法。没有IoC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。
|
|
|
+
|
|
|
+采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
|
|
|
+**控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。**
|
|
|
+
|
|
|
+# 3、HelloSpring
|
|
|
+
|
|
|
+***
|
|
|
+
|
|
|
+1. 新建一个maven项目,编写实体类
|
|
|
+
|
|
|
+```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 + '\'' +
|
|
|
+ '}';
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+2. 编写xml配置文件
|
|
|
+
|
|
|
+```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
|
|
|
+ https://www.springframework.org/schema/beans/spring-beans.xsd">
|
|
|
+
|
|
|
+
|
|
|
+ <!--使用Spring来创建对象,在Spring这些都称为Bean
|
|
|
+ 类型 变量名 = new 类型();
|
|
|
+ Hello hello = new Hello();
|
|
|
+
|
|
|
+ id = 变量名
|
|
|
+ class = new的对象
|
|
|
+ property 相当于给对象中的属性设置一个值!
|
|
|
+ ref:引用Spring创建好的对象
|
|
|
+ value: 具体的值,基本数据类型
|
|
|
+ -->
|
|
|
+ <bean id="hello" class="com.kuang.pojo.Hello">
|
|
|
+ <property name="str" value="Spring"/>
|
|
|
+ </bean>
|
|
|
+</beans>
|
|
|
+```
|
|
|
+
|
|
|
+3. 测试
|
|
|
+
|
|
|
+```java
|
|
|
+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.toString());
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**思考问题?**
|
|
|
+
|
|
|
+- Hello对象是谁创建的?
|
|
|
+ Hello对象是由Spring创建的。
|
|
|
+- Hello对象的属性是怎么设置的?
|
|
|
+ Hello对象的属性是由Spring容器设置的。
|
|
|
+
|
|
|
+这个过程就叫控制反转:
|
|
|
+
|
|
|
+**控制**:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的。
|
|
|
+
|
|
|
+**反转**:程序本身不创建对象,而变成被动的接收对象。
|
|
|
+
|
|
|
+**依赖注入**:就是利用set方法来进行注入的。
|
|
|
+
|
|
|
+IOC是一种编程思想,由主动的编程变成被动的接收。
|
|
|
+
|
|
|
+可以通过new ClassPathXmlApplicationContext去浏览一下底层源码。
|
|
|
+
|
|
|
+**OK,到了现在,我们彻底不用在程序中去改动了,要实现不同的操作,只需要在xml配置文件中进行修改,所谓的IOC,一句话搞定:对象由Spring来创建,管理,装配!**
|
|
|
+
|
|
|
+# 4、IOC创建对象的方式
|
|
|
+
|
|
|
+***
|
|
|
+
|
|
|
+1. 使用无参构造创建对象,默认!
|
|
|
+
|
|
|
+2. 假设我们要使用有参构造创建对象。
|
|
|
+
|
|
|
+ 1. 下标赋值
|
|
|
+
|
|
|
+ ```xml
|
|
|
+ <!--第一种方式:下标赋值 -->
|
|
|
+ <bean id="user" class="com.kuang.pojo.User">
|
|
|
+ <constructor-arg index="0" value="狂神说Java"/>
|
|
|
+ </bean>
|
|
|
+ ```
|
|
|
+
|
|
|
+ 2. 类型
|
|
|
+
|
|
|
+ ```xml
|
|
|
+ <!--第二种方式:通过类型的创建,不建议使用 -->
|
|
|
+ <bean id="user" class="com.kuang.pojo.User">
|
|
|
+ <constructor-arg type="java.lang.String" value="lifa"/>
|
|
|
+ </bean>
|
|
|
+ ```
|
|
|
+
|
|
|
+ 3. 参数名
|
|
|
+
|
|
|
+ ```xml
|
|
|
+ <!--第三种方式:直接通过参数名来设置 -->
|
|
|
+ <bean id="user" class="com.kuang.pojo.User">
|
|
|
+ <constructor-arg name="name" value="李发"/>
|
|
|
+ </bean>
|
|
|
+ ```
|
|
|
+
|
|
|
+总结:在配置文件加载的时候,容器中管理的所有对象就已经初始化了!只有一份!!!
|
|
|
+
|
|
|
+```java
|
|
|
+ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
|
|
|
+ User user = (User) context.getBean("user");
|
|
|
+ user.setName("123");
|
|
|
+ User user2 = (User) context.getBean("user");
|
|
|
+ System.out.println(user == user2); // true
|
|
|
+ System.out.println(user2.getName()); // 123
|
|
|
+```
|
|
|
+
|
|
|
+# 5、Spring配置
|
|
|
+
|
|
|
+***
|
|
|
+
|
|
|
+## 5.1 别名
|
|
|
+
|
|
|
+```xml
|
|
|
+ <!--别名,如果添加了别名,我们也可以使用别名获取到这个对象-->
|
|
|
+ <alias name="user" alias="userNew"/>
|
|
|
+```
|
|
|
+
|
|
|
+## 5.2 Bean配置
|
|
|
+
|
|
|
+```xml
|
|
|
+ <!--
|
|
|
+ id:bean的唯一标识符,也就是相当于我们学的对象名
|
|
|
+ class:bean对象所对应的全限定名:包名+类名
|
|
|
+ name:也是别名,而且name可以同时取多个别名
|
|
|
+ 可以通过空格,逗号,分号分隔
|
|
|
+ -->
|
|
|
+ <bean id="userT" class="com.kuang.pojo.UserT" name="user2 u2,u3;u4">
|
|
|
+ <property name="name" value="黑心白莲"/>
|
|
|
+ </bean>
|
|
|
+```
|
|
|
+
|
|
|
+## 5.3 import
|
|
|
+
|
|
|
+这个import。一般用于团队开发使用,它可以将多个配置文件,导入合并为一个。
|
|
|
+假设,现在项目中有多个人开发,这三个人负责不同的类开发,不同的类需要注册在不同的bean中,我们可以利用import将所有人的beans.xml合并为一个总的!
|
|
|
+
|
|
|
+- 张三
|
|
|
+
|
|
|
+- 李四
|
|
|
+
|
|
|
+- 王五
|
|
|
+
|
|
|
+- applicationContext.xml
|
|
|
+
|
|
|
+ ```xml
|
|
|
+ <import resource="bean.xml"/>
|
|
|
+ <import resource="bean2.xml"/>
|
|
|
+ <import resource="bean3.xml"/>
|
|
|
+ ```
|
|
|
+
|
|
|
+使用的时候,直接使用总的配置就可以了。
|
|
|
+
|
|
|
+# 6、依赖注入
|
|
|
+
|
|
|
+***
|
|
|
+
|
|
|
+## 6.1 、构造器注入
|
|
|
+
|
|
|
+前面已经介绍过,参考**4、IOC创建对象的方式**
|
|
|
+
|
|
|
+## 6.2 、Set方式注入【重点】
|
|
|
+
|
|
|
+- 依赖注入:Set注入
|
|
|
+ - 依赖:bean对象的创建依赖于容器!
|
|
|
+ - 注入:bean对象中的所有属性,由容器来注入!
|
|
|
+
|
|
|
+【环境搭建】
|
|
|
+
|
|
|
+1. 复杂类型
|
|
|
+
|
|
|
+```java
|
|
|
+public class Address {
|
|
|
+ private String address;
|
|
|
+
|
|
|
+ public String getAddress() {
|
|
|
+ return address;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setAddress(String address) {
|
|
|
+ this.address = address;
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+2. 真实测试对象
|
|
|
+
|
|
|
+```java
|
|
|
+public class Student {
|
|
|
+
|
|
|
+ private String name;
|
|
|
+ private Address address;
|
|
|
+ private String[] books;
|
|
|
+ private List<String> hobbies;
|
|
|
+ private Map<String,String> card;
|
|
|
+ private Set<String> games;
|
|
|
+ private String wife;
|
|
|
+ private Properties info;
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+3. beans.xml
|
|
|
+
|
|
|
+```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
|
|
|
+ https://www.springframework.org/schema/beans/spring-beans.xsd">
|
|
|
+
|
|
|
+ <bean id="student" class="com.kuang.pojo.Student">
|
|
|
+ <!--第一种:普通值注入,value -->
|
|
|
+ <property name="name" value="黑心白莲"/>
|
|
|
+ </bean>
|
|
|
+</beans>
|
|
|
+```
|
|
|
+
|
|
|
+4. 测试类
|
|
|
+
|
|
|
+```java
|
|
|
+public class MyTest {
|
|
|
+ public static void main(String[] args) {
|
|
|
+ ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
|
|
|
+
|
|
|
+ Student student = (Student) context.getBean("student");
|
|
|
+ System.out.println(student.getName());
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+5. 完善注入信息
|
|
|
+
|
|
|
+```xml
|
|
|
+ <bean id="address" class="com.kuang.pojo.Address">
|
|
|
+ <property name="address" value="西安"/>
|
|
|
+ </bean>
|
|
|
+
|
|
|
+ <bean id="student" class="com.kuang.pojo.Student">
|
|
|
+ <!--第一种:普通值注入,value -->
|
|
|
+ <property name="name" value="黑心白莲"/>
|
|
|
+
|
|
|
+ <!--第二种: -->
|
|
|
+ <property name="address" ref="address"/>
|
|
|
+
|
|
|
+ <!--数组 -->
|
|
|
+ <property name="books">
|
|
|
+ <array>
|
|
|
+ <value>红楼梦</value>
|
|
|
+ <value>西游记</value>
|
|
|
+ <value>水浒传</value>
|
|
|
+ <value>三国演义</value>
|
|
|
+ </array>
|
|
|
+ </property>
|
|
|
+
|
|
|
+ <!--List -->
|
|
|
+ <property name="hobbies">
|
|
|
+ <list>
|
|
|
+ <value>打篮球</value>
|
|
|
+ <value>看电影</value>
|
|
|
+ <value>敲代码</value>
|
|
|
+ </list>
|
|
|
+ </property>
|
|
|
+
|
|
|
+ <!--Map -->
|
|
|
+ <property name="card">
|
|
|
+ <map>
|
|
|
+ <entry key="身份证" value="123456789987456321"/>
|
|
|
+ <entry key="银行卡" value="359419496419481649"/>
|
|
|
+ </map>
|
|
|
+ </property>
|
|
|
+
|
|
|
+ <!--Set -->
|
|
|
+ <property name="games">
|
|
|
+ <set>
|
|
|
+ <value>LOL</value>
|
|
|
+ <value>COC</value>
|
|
|
+ <value>BOB</value>
|
|
|
+ </set>
|
|
|
+ </property>
|
|
|
+
|
|
|
+ <!--NULL -->
|
|
|
+ <property name="wife">
|
|
|
+ <null/>
|
|
|
+ </property>
|
|
|
+
|
|
|
+ <!--Properties -->
|
|
|
+ <property name="info">
|
|
|
+ <props>
|
|
|
+ <prop key="driver">20191029</prop>
|
|
|
+ <prop key="url">102.0913.524.4585</prop>
|
|
|
+ <prop key="user">黑心白莲</prop>
|
|
|
+ <prop key="password">123456</prop>
|
|
|
+ </props>
|
|
|
+ </property>
|
|
|
+
|
|
|
+ </bean>
|
|
|
+```
|
|
|
+
|
|
|
+## 6.3 、拓展方式注入
|
|
|
+
|
|
|
+我们可以使用p命名空间和c命名空间进行注入
|
|
|
+
|
|
|
+官方解释:
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+使用:
|
|
|
+
|
|
|
+```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"
|
|
|
+ xmlns:p="http://www.springframework.org/schema/p"
|
|
|
+ xmlns:c="http://www.springframework.org/schema/c"
|
|
|
+ xsi:schemaLocation="http://www.springframework.org/schema/beans
|
|
|
+ https://www.springframework.org/schema/beans/spring-beans.xsd">
|
|
|
+
|
|
|
+ <!--p命名空间注入,可以直接注入属性的值:property-->
|
|
|
+ <bean id="user" class="com.kuang.pojo.User" p:name="黑心白莲" p:age="20"/>
|
|
|
+
|
|
|
+ <!--c命名空间注入,通过构造器注入:constructor-args-->
|
|
|
+ <bean id="user2" class="com.kuang.pojo.User" c:name="狂神" c:age="22"/>
|
|
|
+
|
|
|
+</beans>
|
|
|
+```
|
|
|
+
|
|
|
+测试:
|
|
|
+
|
|
|
+```java
|
|
|
+ @Test
|
|
|
+ public void test2(){
|
|
|
+ ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
|
|
|
+
|
|
|
+ User user = context.getBean("user",User.class);
|
|
|
+ System.out.println(user);
|
|
|
+
|
|
|
+ User user2 = context.getBean("user2",User.class);
|
|
|
+ System.out.println(user2);
|
|
|
+ }
|
|
|
+```
|
|
|
+
|
|
|
+注意点:p命名空间和c命名空间不能直接使用,需要导入xml约束
|
|
|
+
|
|
|
+```xml
|
|
|
+ xmlns:p="http://www.springframework.org/schema/p"
|
|
|
+ xmlns:c="http://www.springframework.org/schema/c"
|
|
|
+```
|
|
|
+
|
|
|
+## 6.4 、bean的作用域
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+1. 单例模式(Spring默认机制)
|
|
|
+
|
|
|
+```xml
|
|
|
+<bean id="user2" class="com.kuang.pojo.User" c:name="狂神" c:age="22" scope="singleton"/>
|
|
|
+```
|
|
|
+
|
|
|
+2. 原型模式:每次从容器中get的时候,都会产生一个新对象!
|
|
|
+
|
|
|
+```xml
|
|
|
+<bean id="user2" class="com.kuang.pojo.User" c:name="狂神" c:age="22" scope="prototype"/>
|
|
|
+```
|
|
|
+
|
|
|
+3. 其余的request、session、application、这些只能在web开发中用到!
|
|
|
+
|
|
|
+# 7、bean的自动装配
|
|
|
+
|
|
|
+***
|
|
|
+
|
|
|
+- 自动装配是Spring满足bean依赖的一种方式
|
|
|
+- Spring会在上下文中自动寻找,并自动给bean装配属性
|
|
|
+
|
|
|
+在Spring中有三种装配的方式:
|
|
|
+
|
|
|
+1. 在xml中显式的配置;
|
|
|
+2. 在java中显式配置;
|
|
|
+3. 隐式的自动装配bean【重要】
|
|
|
+
|
|
|
+## 7.1 、测试
|
|
|
+
|
|
|
+环境搭建:创建项目,一个人有两个宠物!
|
|
|
+
|
|
|
+```xml
|
|
|
+ <bean id="cat" class="com.kuang.pojo.Cat"/>
|
|
|
+ <bean id="dog" class="com.kuang.pojo.Dog"/>
|
|
|
+
|
|
|
+ <bean id="people" class="com.kuang.pojo.People">
|
|
|
+ <property name="name" value="小白莲"/>
|
|
|
+ <property name="cat" ref="cat"/>
|
|
|
+ <property name="dog" ref="dog"/>
|
|
|
+ </bean>
|
|
|
+```
|
|
|
+
|
|
|
+## 7.2、 ByName自动装配
|
|
|
+
|
|
|
+```xml
|
|
|
+ <!--
|
|
|
+ byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean id!
|
|
|
+ 这里的id值得是set后面的值,会自动转换为小写
|
|
|
+ -->
|
|
|
+ <bean id="people" class="com.kuang.pojo.People" autowire="byName">
|
|
|
+ <property name="name" value="小白莲"/>
|
|
|
+ </bean>
|
|
|
+```
|
|
|
+
|
|
|
+## 7.3 、ByType自动装配
|
|
|
+
|
|
|
+```xml
|
|
|
+ <!--
|
|
|
+ byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean!
|
|
|
+ 必须唯一,不能有两个
|
|
|
+ -->
|
|
|
+ <bean id="people" class="com.kuang.pojo.People" autowire="byType">
|
|
|
+ <property name="name" value="小白莲"/>
|
|
|
+ </bean>
|
|
|
+```
|
|
|
+
|
|
|
+小结:
|
|
|
+
|
|
|
+- ByName的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致!
|
|
|
+- ByType的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致!
|
|
|
+
|
|
|
+## 7.4 、使用注解实现自动装配
|
|
|
+
|
|
|
+jdk1.5支持的注解,Spring2.5就支持注解了!
|
|
|
+
|
|
|
+要使用注解须知:
|
|
|
+
|
|
|
+1. 导入约束
|
|
|
+
|
|
|
+2. 配置注解的支持
|
|
|
+
|
|
|
+ ```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"
|
|
|
+ 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方法上使用!
|
|
|
+
|
|
|
+使用Autowried我们就可以不用编写set方法了,前提是你这个自动配置的属性在IOC(Spring)容器中存在,且符合名字ByName!
|
|
|
+
|
|
|
+**科普:**
|
|
|
+
|
|
|
+> @Nullable 字段标记了了这个注解,说明这个字段可以为null;
|
|
|
+
|
|
|
+```java
|
|
|
+public @interface Autowired {
|
|
|
+ boolean required() default true;
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+测试代码
|
|
|
+
|
|
|
+```java
|
|
|
+public class People {
|
|
|
+ //如果显式定义了Autowired的required属性为false,说明这个对象可以为null,否则不允许为空
|
|
|
+ @Autowired(required = false)
|
|
|
+ private Cat cat;
|
|
|
+ @Autowired
|
|
|
+ private Dog dog;
|
|
|
+ private String name;
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以使用@Qualifier(value = “xxx”)去配置@Autowired的使用,指定一个唯一的bean对象注入!
|
|
|
+
|
|
|
+```java
|
|
|
+public class People {
|
|
|
+ @Autowired
|
|
|
+ @Qualifier(value = "cat111")
|
|
|
+ private Cat cat;
|
|
|
+ @Autowired
|
|
|
+ @Qualifier(value = "dog222")
|
|
|
+ private Dog dog;
|
|
|
+ private String name;
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+**@Resource**
|
|
|
+
|
|
|
+```java
|
|
|
+public class People {
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private Cat cat;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private Dog dog;
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+小结:
|
|
|
+
|
|
|
+@Resource和@Autowired的区别:
|
|
|
+
|
|
|
+- 都是用来自动装配的,都可以放在属性字段上
|
|
|
+- @Autowired通过byType的方式实现,而且必须要求这个对象存在!【常用】
|
|
|
+- @Resource默认通过byName的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错!【常用】
|
|
|
+- 执行顺序不同:@Autowired通过byType的方式实现。@Resource默认通过byName的方式实现
|
|
|
+
|
|
|
+# 8、使用注解开发
|
|
|
+
|
|
|
+***
|
|
|
+
|
|
|
+在Spring4之后,要使用注解开发,必须要保证aop的包导入了
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+使用注解需要导入约束,配置注解的支持!
|
|
|
+
|
|
|
+```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"
|
|
|
+ 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>
|
|
|
+```
|
|
|
+
|
|
|
+> **Bean的实现**
|
|
|
+
|
|
|
+我们之前都是使用 bean 的标签进行bean注入,但是实际开发中,我们一般都会使用注解!
|
|
|
+
|
|
|
+1. 配置扫描那些包下的注解
|
|
|
+
|
|
|
+```xml
|
|
|
+<!--指定注解扫描包-->
|
|
|
+<context:component-scan base-package="com.kuang.pojo"/>
|
|
|
+```
|
|
|
+
|
|
|
+2. 在指定包下编写类,增加注释
|
|
|
+
|
|
|
+```java
|
|
|
+@Component("user")
|
|
|
+// 相当于配置文件中 <bean id="user" class="当前注解的类"/>
|
|
|
+public class User {
|
|
|
+ public String name = "秦疆";
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+3. 测试
|
|
|
+
|
|
|
+```java
|
|
|
+@Test
|
|
|
+public void test(){
|
|
|
+ ApplicationContext applicationContext =
|
|
|
+ new ClassPathXmlApplicationContext("beans.xml");
|
|
|
+ User user = (User) applicationContext.getBean("user");
|
|
|
+ System.out.println(user.name);
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+> **属性注入**
|
|
|
+
|
|
|
+使用注解注入属性
|
|
|
+
|
|
|
+1. 可以不用提供set方法,直接在直接名上添加@value("值")
|
|
|
+
|
|
|
+ ```java
|
|
|
+ @Component("user")
|
|
|
+ // 相当于配置文件中 <bean id="user" class="当前注解的类"/>
|
|
|
+ public class User {
|
|
|
+ @Value("秦疆")
|
|
|
+ // 相当于配置文件中 <property name="name" value="秦疆"/>
|
|
|
+ public String name;
|
|
|
+ }
|
|
|
+ ```
|
|
|
+
|
|
|
+2. 如果提供了set方法,在set方法上添加@value("值")
|
|
|
+
|
|
|
+ ```java
|
|
|
+ @Component("user")
|
|
|
+ public class User {
|
|
|
+
|
|
|
+ public String name;
|
|
|
+
|
|
|
+ @Value("秦疆")
|
|
|
+ public void setName(String name) {
|
|
|
+ this.name = name;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ```
|
|
|
+
|
|
|
+> **衍生注解**
|
|
|
+
|
|
|
+我们这些注解,就是替代了在配置文件当中配置步骤而已!更加的方便快捷!
|
|
|
+
|
|
|
+**@Component三个衍生注解**
|
|
|
+
|
|
|
+为了更好的进行分层,Spring可以使用其它三个注解,功能一样,目前使用哪一个功能都一样。
|
|
|
+
|
|
|
+- @Controller: web层
|
|
|
+- @Service:service层
|
|
|
+- @Repository:dao层
|
|
|
+
|
|
|
+写上这些注释,就相当于将这个类交给Spring管理装配了!
|
|
|
+
|
|
|
+> **自动装配注解**
|
|
|
+
|
|
|
+在Bean的自动装配已经讲过了,可以回顾!
|
|
|
+
|
|
|
+- @Autowired:自动装配通过类型,名字。如果Autowired不能唯一自动装配上属性,则需要通过@Qualifier(value = "xxx")去配置。
|
|
|
+- @Nullable 字段标记了了这个注解,说明这个字段可以为null;
|
|
|
+- @Resource:自动装配通过名字,类型。
|
|
|
+
|
|
|
+> **作用域**
|
|
|
+
|
|
|
+@scope
|
|
|
+
|
|
|
+- singleton:默认的,Spring会采用单例模式创建这个对象。关闭工厂 ,所有的对象都会销毁。
|
|
|
+- prototype:多例模式。关闭工厂 ,所有的对象不会销毁。内部的垃圾回收机制会回收
|
|
|
+
|
|
|
+```java
|
|
|
+@Component
|
|
|
+@Scope("singleton")
|
|
|
+public class User {
|
|
|
+
|
|
|
+ //相当于 <property name="name" value="白莲"/>
|
|
|
+ @Value("白莲")
|
|
|
+ public String name;
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+> **小结**
|
|
|
+
|
|
|
+**xml与注解:**
|
|
|
+
|
|
|
+- xml更加万能,适用于任何场合!维护简单方便
|
|
|
+- 注解不是自己类使用不了,维护相队复杂!
|
|
|
+
|
|
|
+**xml与注解最佳实践:**
|
|
|
+
|
|
|
+- xml用来管理bean;
|
|
|
+- 注解只负责完成属性的注入;
|
|
|
+- 我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持
|
|
|
+
|
|
|
+```xml
|
|
|
+ <!--指定要扫描的包,这个包下的注解就会生效-->
|
|
|
+ <context:component-scan base-package="com.kuang"/>
|
|
|
+ <!--开启注解的支持 -->
|
|
|
+ <context:annotation-config/>
|
|
|
+```
|
|
|
+
|
|
|
+作用:
|
|
|
+
|
|
|
+- 进行注解驱动注册,从而使注解生效
|
|
|
+- 用于激活那些已经在spring容器里注册过的bean上面的注解,也就是显示的向Spring注册
|
|
|
+- 如果不扫描包,就需要手动配置bean
|
|
|
+- 如果不加注解驱动,则注入的值为null!
|
|
|
+
|
|
|
+# 9、使用Java的方式配置Spring
|
|
|
+
|
|
|
+***
|
|
|
+
|
|
|
+JavaConfig 原来是 Spring 的一个子项目,它通过 Java 类的方式提供 Bean 的定义信息,在 Spring4 的版本, JavaConfig 已正式成为 Spring4 的核心功能 。
|
|
|
+
|
|
|
+实体类
|
|
|
+
|
|
|
+```java
|
|
|
+//这里这个注解的意思,就是说明这个类被Spring接管了,注册到了容器中
|
|
|
+@Component
|
|
|
+public class User {
|
|
|
+ private String name;
|
|
|
+
|
|
|
+ public String getName() {
|
|
|
+ return name;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Value("黑心白莲") //属性注入值
|
|
|
+ public void setName(String name) {
|
|
|
+ this.name = name;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String toString() {
|
|
|
+ return "User{" +
|
|
|
+ "name='" + name + '\'' +
|
|
|
+ '}';
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+配置文件
|
|
|
+
|
|
|
+```java
|
|
|
+// 这个也会Spring容器托管,注册到容器中,因为它本来就是一个@Component
|
|
|
+// @Configuration代表这是一个配置类,就和我们之前看的beans.xml
|
|
|
+@Configuration
|
|
|
+@ComponentScan("com.kuang.pojo")
|
|
|
+// 引入多个配置类,合并
|
|
|
+@Import(KuangConfig2.class)
|
|
|
+public class KuangConfig {
|
|
|
+
|
|
|
+ // 注册一个bean,就相当于我们之前写的一个bean标签
|
|
|
+ // 这个方法的名字,就相当于bean标签中id属性
|
|
|
+ // 这个方法的返回值,就相当于bean标签中的class属性
|
|
|
+ @Bean
|
|
|
+ public User user(){
|
|
|
+ return new User(); // 就是返回要注入到bean的对象!
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+测试类
|
|
|
+
|
|
|
+```java
|
|
|
+public class MyTest {
|
|
|
+ public static void main(String[] args) {
|
|
|
+
|
|
|
+ //如果完全使用了配置类方式去做,我们就只能通过 AnnotationConfig 上下文来获取容器,通过配置类的class对象加载!
|
|
|
+ ApplicationContext context = new AnnotationConfigApplicationContext(KuangConfig.class);
|
|
|
+
|
|
|
+ User user = context.getBean("user", User.class);
|
|
|
+ System.out.println(user.getName());
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+这种纯Java的配置方式,在SpringBoot中随处可见!
|
|
|
+
|