当前位置: 首页 > news >正文

【沉浸式求职学习day53】【Spring】

沉浸式求职学习

  • 1、Spring
    • 1.1 简介
    • 1.2 优点
    • 1.3 组成
    • 1.4 拓展
  • 2、IOC理论推导
    • 2.1 引例
    • 2.2 IOC的本质
  • 3、HelloSpring
  • 4、IOC创建对象方式
    • 4.1 方式一
    • 4.2 方式二
  • 5、Spring配置
    • 5.1 别名
    • 5.2 Bean的配置
    • 5.3 import
  • 6、依赖注入
    • 6.1 构造器注入
    • 6.2 Set 注入 (重点)
    • 6.3 拓展方式注入
    • 6.4 Bean的作用域
      • 6.4.1 Singleton(单例)
      • 6.4.2 Prototype(原型)
  • 7、自动装配Bean
    • 7.1 测试
    • 7.2 ByName自动装配
    • 7.3 ByType自动装配
    • 7.4 使用注解实现自动装配
      • @Autowired
  • 8、使用注解开发
    • 8.1 bean
    • 8.2 属性如何注入
    • 8.3 衍生的注解
    • 8.4 自动装配置
    • 8.5 作用域
    • 8.6 小结
  • 9、使用Java的方式进行配置

好久不见,最近很忙,所以只是学习没有分享,今天多分享一些~

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!

  1. 官网:https://spring.io/projects/spring-framework#overview
  2. 官方下载地址: http://repo.spring.io/release/org/springframework/spring
  3. 官方文档:https://docs.spring.io/spring-framework/docs/current/reference/html/core.html
  4. 中文版官方文档:https://www.docs4dev.com/docs/zh/spring-framework/5.1.3.RELEASE/reference

1.2 优点

  • Spring是一个开源免费的框架(容器)!
  • Spring是一个轻量级的、非入侵式的框架!
  • 控制反转(IOC),面向切面编程(AOP)!
  • 支持事务的处理,对框架整合的支持!

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

1.3 组成

参考:https://docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/overview.html

1.4 拓展

  • 在Spring的官网有这个介绍:现代化的Java开发!说白了就是基于Spring的开发!
    在这里插入图片描述
  • Spring Boot
    • 一个快速开发的脚手架。
    • 基于Spring Boot 可以快速开发单个微服务。
    • 约定大于配置!
  • Spring Cloud
    • Spring Clound 是基于Spring Boot 实现的。

为什么要学Spring?

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

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

2、IOC理论推导

2.1 引例

在这里插入图片描述
在这里插入图片描述
UserDao 接口

package com.github.subei.dao;public interface UserDao {void getUser();
}

UserDaoImpl 实现类:

package com.github.subei.dao;public class UserDaoImpl implements UserDao{public void getUser() {System.out.println("默认获取用户的数据……");}
}

UserService 业务接口

package com.github.subei.service;public interface UserService {void getUser();
}

UserServiceImpl 业务实现类

package com.github.subei.service;import com.github.subei.dao.UserDao;
import com.github.subei.dao.UserDaoImpl;public class UserServiceImpl implements UserService{private UserDao userDao = new UserDaoImpl();public void getUser() {userDao.getUser();}
}

测试类MyTest

import com.github.subei.service.UserServiceImpl;public class MyTest {public static void main(String[] args) {// 用户实际调用的是业务层,dao层不需要接触UserServiceImpl userService = new UserServiceImpl();userService.getUser();}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在我们之前的业务中,用户的需求可能会影响我们原来的代码,我们需要根据用户的需求去修改原代码!如果程序代码量十分大,修改一次的成本十分昂贵。

  • 我们使用一个set接口实现。修改UserServiceImpl.java文件
package com.github.subei.service;import com.github.subei.dao.UserDao;public class UserServiceImpl implements UserService{
//    private UserDao userDao = new UserDaoImpl();private UserDao userDao;// 利用set进行动态实现值的注入!!public void setUserDao(UserDao userDao){this.userDao = userDao;}public void getUser() {userDao.getUser();}
}

测试类

import com.github.subei.dao.UserDaoSqlserverImpl;
import com.github.subei.service.UserServiceImpl;public class MyTest {public static void main(String[] args) {// 用户实际调用的是业务层,dao层不需要接触UserServiceImpl userService = new UserServiceImpl();userService.setUserDao(new UserDaoSqlserverImpl());userService.getUser();}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 之前,程序是主动创建对象!控制权在程序猿手上!
  • 使用了set注入后,程序不再具有主动性,而是变成了被动的接受对象!

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

2.2 IOC的本质

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

  • IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IoC。

  • Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象。

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

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

3、HelloSpring

新建项目,导入Jar包

编写代码:

编写一个Hello实体类

package com.github.subei.pojo;public class Hello {private String src;public String getSrc() {return src;}public void setSrc(String src) {this.src = src;}@Overridepublic String toString() {return "Hello{" +"src='" + src + '\'' +'}';}
}

编写spring文件 , 这里命名为beans.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--使用Spring来创建对象,在spring这些部称Bean--><bean id="hello" class="com.github.subei.pojo.Hello"><property name="src" value="Spring"/></bean></beans>

我们可以去进行测试了 .

import com.github.subei.pojo.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class MyTest {public static void main(String[] args) {//解析beans.xml文件 , 生成管理相应的Bean对象ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");//getBean : 参数即为spring配置文件中bean的id .Hello hello = (Hello) context.getBean("hello");System.out.println(hello.toString());}
}

在这里插入图片描述

思考:

  • Hello 对象是谁创建的 ?
    • hello 对象是由Spring创建的。
  • Hello 对象的属性是怎么设置的 ?
    • hello 对象的属性是由Spring容器设置的。

这个过程就叫控制反转:

  • 控制 : 谁来控制对象的创建 , 传统应用程序的对象是由程序本身控制创建的 , 使用Spring后 , 对象是由Spring来创建的。
  • 反转 : 程序本身不创建对象 , 而变成被动的接收对象。

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

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

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

修改案例一:
在案例一中, 新增一个Spring配置文件beans.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="mysqlImpl" class="com.github.subei.dao.UserDaoMysqlImpl"/><bean id="oracleImpl" class="com.github.subei.dao.UserDaoOracleImpl"/><bean id="UserServiceImpl" class="com.github.subei.service.UserServiceImpl"><!--ref:引用spring容器中创建好的对象!value:具体的值,基本数帮类型!--><property name="userDao" ref="mysqlImpl"/></bean></beans>

测试:

    @Testpublic void test2(){// 获取AppLicationcontext;拿到Spring容器ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");UserServiceImpl serviceImpl = (UserServiceImpl) context.getBean("UserServiceImpl");serviceImpl.getUser();}

在这里插入图片描述
在这里插入图片描述

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

4、IOC创建对象方式

4.1 方式一

方式一:通过无参构造方法来创建。

User.java

package com.github.subei.pojo;public class User {private String name;public User() {System.out.println("User的无参构造!");}public String getName() {return name;}public void setName(String name) {this.name = name;}public void show(){System.out.println("name="+ name );}
}

beans.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="user" class="com.github.subei.pojo.User"><property name="name" value="subei"/></bean></beans>

测试类

import com.github.subei.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class MyTest {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");// 在执行getBean的时候, user已经创建好, 通过无参构造User user = (User) context.getBean("user");// 调用对象的方法 .user.show();}
}

在这里插入图片描述
通过debug可以发现,在调用show方法之前,User对象已经通过无参构造初始化了!

4.2 方式二

方式二:通过有参构造方法来创建。

UserT . java

package com.github.subei.pojo;public class UserT {private String name;public UserT(String name) {this.name = name;}public UserT() {System.out.println("UserT被创建了");}public String getName() {return name;}public void setName(String name) {this.name = name;}public void show() {System.out.println("name=" + name);}}

beans.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 第一种:根据index参数下标设置 -->
<!--    <bean id="userT" class="com.github.subei.pojo.UserT">-->
<!--        <constructor-arg index="0" value="subeily——"/>-->
<!--    </bean>--><!-- 第二种:根据参数类型设置,不建议使用 -->
<!--    <bean id="userT" class="com.github.subei.pojo.UserT">-->
<!--        <constructor-arg type="java.lang.String" value="subeily2——"/>-->
<!--    </bean>--><!-- 第三种:根据参数名字设置 --><bean id="userT" class="com.github.subei.pojo.UserT"><!-- name指参数名 --><constructor-arg name="name" value="subeily3——"/></bean></beans>

测试

    @Testpublic void test(){ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");// 在执行getBean的时候, user已经创建好, 通过无参构造UserT user = (UserT) context.getBean("userT");// 调用对象的方法 .user.show();}

在这里插入图片描述
总结:在配置文件加载的时候,容器中管理的对象就已经初始化了!

5、Spring配置

5.1 别名

  • alias 设置别名 , 为bean设置别名 , 可以设置多个别名。

5.2 Bean的配置

    <!--id:bean 的唯一标识符,也就是相当于我们学的对象名class:bean 对象所对应的全限定名:包名+类型name:也是别名,而且name可以同时取多个别名--><bean id="user2" class="com.github.subei.pojo.UserT" name="user2,u2,u3"><property name="name" value="懒羊羊的蛋糕店!"/></bean>

5.3 import

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

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><import resource="beans.xml"/><import resource="beans2.xml"/><import resource="beans3.xml"/></beans>

6、依赖注入

6.1 构造器注入

  • 之前的案例已经说过了。

6.2 Set 注入 (重点)

依赖注入(Set注入!)。

  • 依赖 : Bean对象的创建依赖于容器!
  • 注入 : Bean对象中的所有属性,由容器来设置和装配。
  1. 复杂类型
  • Address.java
package com.github.subei.pojo;public class Address {private String address;public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "Address{" +"address='" + address + '\'' +'}';}
}

真实测试对象

  • Student.java
package com.github.subei.pojo;import java.util.*;public class Student {private String name;private Address address;private String[] books;private List<String> hobby;private Map<String,String> card;private Set<String> games;private String wife;private Properties info;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, String> getCard() {return card;}public void setCard(Map<String, String> card) {this.card = card;}public Set<String> getGames() {return games;}public void setGames(Set<String> games) {this.games = games;}public String getWife() {return wife;}public void setWife(String wife) {this.wife = wife;}public Properties getInfo() {return info;}public void setInfo(Properties info) {this.info = info;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", address=" + address +", books=" + Arrays.toString(books) +", hobby=" + hobby +", card=" + card +", games=" + games +", wife='" + wife + '\'' +", info=" + info +'}';}
}

beans.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="student" class="com.github.subei.pojo.Student"><!-- 第一种:普通值注入,value --><property name="name" value="subei"/></bean></beans>

测试类

import com.github.subei.pojo.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;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());}
}

在这里插入图片描述

6.3 拓展方式注入

  • 我们可以使用p命令空间和c命令空间进行注入

  • 官方解释:
    p命名和c命名注入翻译:

  • p-namespace 允许使用bean元素的属性(而不是嵌套的<property/>元素)来描述协作 Bean 的属性值,或同时使用这两者。

  • c-namespace 允许使用内联属性来配置构造函数参数,而不是嵌套的constructor-arg元素。

User.java

package com.github.subei.pojo;public class User {private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}}

P命名空间注入 : 需要在头文件中加入约束文件

 导入约束 : xmlns:p="http://www.springframework.org/schema/p"<!-- p命名空间注入,可以直接注入属性的值: property --><bean id="user" class="com.github.subei.pojo.User"p:name="subei"p:age="21" />

在这里插入图片描述
c 命名空间注入 : 需要在头文件中加入约束文件

 导入约束 : xmlns:c="http://www.springframework.org/schema/c"<!-- c命名空间注入,可以通过构造器注入: construct-args --><bean id="user2" class="com.github.subei.pojo.User"c:name="subei"c:age="22" />

在这里插入图片描述

6.4 Bean的作用域

在Spring中,那些组成应用程序的主体及由Spring IoC容器所管理的对象,被称之为bean。

简单地讲,bean就是由IoC容器初始化、装配及管理的对象。

ScopeDescription
singleton(默认)将每个 Spring IoC 容器的单个 bean 定义范围限定为单个对象实例。
prototype将单个 bean 定义的作用域限定为任意数量的对象实例。
request将单个 bean 定义的范围限定为单个 HTTP 请求的生命周期。也就是说,每个 HTTP 请求都有一个在单个 bean 定义后面创建的 bean 实例。仅在可感知网络的 Spring ApplicationContext中有效。
session将单个 bean 定义的范围限定为 HTTP Session的生命周期。仅在可感知网络的 Spring ApplicationContext上下文中有效。
application将单个 bean 定义的范围限定为ServletContext的生命周期。仅在可感知网络的 Spring ApplicationContext上下文中有效。
websocket将单个 bean 定义的范围限定为WebSocket的生命周期。仅在可感知网络的 Spring ApplicationContext上下文中有效。

6.4.1 Singleton(单例)

单例模式(Spring默认机制)

  • 下图显示了单例作用域如何工作:

在这里插入图片描述

当一个bean的作用域为Singleton,那么Spring IoC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。Singleton是单例类型,就是在创建起容器时就同时自动创建了一个bean的对象,不管你是否使用,他都存在了,每次获取到的对象都是同一个对象。


  • 注意,Singleton作用域是Spring中的缺省作用域。

6.4.2 Prototype(原型)

原型模式:每次从容器中get的时候,都会产生一个新对象!

每次对特定 bean 提出请求时,bean 部署的非单一原型范围都会导致创建一个新 bean 实例。也就是说,将 Bean 注入到另一个 Bean 中,或者您可以通过容器上的getBean()方法调用来请求它。通常,应将原型作用域用于所有有状态 Bean,将单例作用域用于 StatelessBean。

下图说明了 Spring 原型范围:

在这里插入图片描述

7、自动装配Bean

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

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

  1. 在xml中显示的配置;
  2. 在java中显示配置;
  3. 隐式的自动装配bean。【重要!】

7.1 测试

  • 环境搭建:一个人有两个宠物!
    Cat.java
package com.github.subei.pojo;public class Cat {public void shout(){System.out.println("喵!喵!喵!");}
}

Dog.java

package com.github.subei.pojo;public class Dog {public void shout(){System.out.println("汪!汪!汪!");}
}

People.java

package com.github.subei.pojo;public class People {private Cat cat;private Dog dog;private String name;public Cat getCat() {return cat;}public void setCat(Cat cat) {this.cat = cat;}public Dog getDog() {return dog;}public void setDog(Dog dog) {this.dog = dog;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "People{" +"cat=" + cat +", dog=" + dog +", name='" + name + '\'' +'}';}
}

beans.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="cat" class="com.github.subei.pojo.Cat"/><bean id="dog" class="com.github.subei.pojo.Dog"/><bean id="people" class="com.github.subei.pojo.People"><property name="name" value="哇哈哈"/><property name="cat" ref="cat"/><property name="dog" ref="dog"/></bean></beans>

测试类

import com.github.subei.pojo.People;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class MyTest {@Testpublic void test(){ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");People people = context.getBean("people", People.class);people.getCat().shout();people.getDog().shout();}
}

在这里插入图片描述

7.2 ByName自动装配

    <!--byName:会自动在容器上下文中查找,和自己对象set方法后而的值对应的beanid!--><bean id="people" class="com.github.subei.pojo.People" autowire="byName"><property name="name" value="哇哈哈"/></bean>

在这里插入图片描述

7.3 ByType自动装配

    <bean class="com.github.subei.pojo.Cat"/><bean class="com.github.subei.pojo.Dog"/><!--byName:会自动在容器上下文中查找,和自己对象set方法后而的值对应的beanid!byType:会自动在容器上下文中查找,和自己对象属性类型机同的bean!--><bean id="people" class="com.github.subei.pojo.People" autowire="byType"><property name="name" value="哇哈哈"/></bean>

在这里插入图片描述
小结:

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

7.4 使用注解实现自动装配

  • JDK 1.5支持的注解,Spring2.5就支持注解了!
  • The introduction of annotation-based configuration raised the question of whether this approach is “better” than XML.
  • 要使用注解须知:
    • 导入约束,context约束
    • 配置注解的支持;context:annotation-config/
<?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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsd"><context:annotation-config/></beans>

@Autowired

  • 修改beans.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"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/context/spring-aop.xsd"><!-- 开启注解的支持 --><context:annotation-config/><bean id="cat" class="com.github.subei.pojo.Cat"/><bean id="dog" class="com.github.subei.pojo.Dog"/><bean id="people" class="com.github.subei.pojo.People"/></beans>

修改People.java文件

package com.github.subei.pojo;import org.springframework.beans.factory.annotation.Autowired;public class People {@Autowiredprivate Cat cat;@Autowiredprivate Dog dog;private String name;public Cat getCat() {return cat;}public Dog getDog() {return dog;}public String getName() {return name;}@Overridepublic String toString() {return "People{" +"cat=" + cat +", dog=" + dog +", name='" + name + '\'' +'}';}
}

在这里插入图片描述

  • 直接在属性上使用!也可以在set方式上使用!
  • 使用Autowired我们可以不用编写Set方法了,前提是你这个自动装配的属性在IOC(Spring)容器中存在,且符合名字byname!

如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候、我们可以使用@Qualifier(value=“xxx”)去配置@Autowired的使用,指定一个唯一的bean对象注入!
在这里插入图片描述

package com.github.subei.pojo;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;public class People {@Autowired@Qualifier(value = "cat111")private Cat cat;@Autowired@Qualifier(value = "dog222")private Dog dog;private String name;public Cat getCat() {return cat;}public Dog getDog() {return dog;}public String getName() {return name;}@Overridepublic String toString() {return "People{" +"cat=" + cat +", dog=" + dog +", name='" + name + '\'' +'}';}
}

在这里插入图片描述
小结,@Resource 和@Autowired的区别:

  • 都是用来自动装配的,都可以放在属性字段上!
  • @Autowired 通过byType的方式实现,而且必须要求这个对象存在!
  • @Resource默认通过byname的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的倩况下,就报错!【常用】
  • 执行顺序不同:@Autowired通过byType的方式实现。@Resource默认通过byname的方式实现。

8、使用注解开发

在Spring4之后,要使用注解开发,必须要保证 aop的包导入了。

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

8.1 bean

<?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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"></beans>

配置扫描包下的注解

    <!-- 指定要扫描的包,这个包下的注解就会生效! --><context:component-scan base-package="com.github.subei.pojo"/>

在指定包下编写类,增加注解

package com.github.subei.pojo;import org.springframework.stereotype.Component;// 等价于  <bean id="user" class="com.github.subei.pojo.User"/>
// @Component 组件
@Component
public class User {public String name = "哇哈哈";
}

测试类

import com.github.subei.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class MyTest {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");User user = (User)context.getBean("user",User.class);System.out.println(user.name);}
}

在这里插入图片描述

8.2 属性如何注入

package com.github.subei.pojo;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;// 等价于  <bean id="user" class="com.github.subei.pojo.User"/>
// @Component 组件
@Component
public class User {// 相当于  <property name="name" value="subeiLY"/>@Value("subeiLY")public String name;public void setName(String name) {this.name = name;}
}

在这里插入图片描述

8.3 衍生的注解

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

    • dao:【@Repository】
    • service:【@Service】
    • controller:【@Controller】
  • 这四个注解功能都是一样的,都是代表将某个类注册到Spring中,装配Bean。

8.4 自动装配置

参考Bean的自动装配!

  • @Autowired:自动装配通过类型。名字
    如果Autowired不能唯一自动装配上属性,则需要通过@Qualifier(value=“xxx”)
  • @Nullable字段标记了这个注解,说明这个字段可以为null;
  • @Resource:自动装配通过名字。类型。

8.5 作用域

@Scope

  • singleton:默认的,Spring会采用单例模式创建这个对象。关闭工厂 ,所有的对象都会销毁。
  • prototype:原型模式。关闭工厂 ,所有的对象不会销毁。内部的垃圾回收机制会回收
package com.github.subei.pojo;import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;// 等价于  <bean id="user" class="com.github.subei.pojo.User"/>
// @Component 组件
@Component
//@Scope("singleton") //单例模式
@Scope("prototype") //原型模式
public class User {// 相当于  <property name="name" value="subeiLY"/>@Value("subeiLY")public String name;public void setName(String name) {this.name = name;}
}

8.6 小结

XML与注解比较

  • XML可以适用任何场景 ,结构清晰,维护方便。
  • 注解,不是自己提供的类使用不了,维护相对复杂。

xml与注解整合开发

  • xml用来管理Bean。
  • 注解只负责完成属性注入。
  • 在使用过程中, 只需要注意一个问题:必须让注解生效,就需要开启注解的支持。

9、使用Java的方式进行配置

  • 我们现在要完全不使用Spring的xml配置了,全权交给Java来做!
  • JavaConfig 原来是 Spring 的一个子项目,在 Spring4 的版本, JavaConfig 已正式成为 Spring4 的核心功能 。

测试类

  1. 编写一个实体类,User
package com.github.subei.pojo;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;@Component  // 将这个类标注为Spring的一个组件,放到容器中!
public class User {private String name;public String getName() {return name;}@Value("KANGSHIFU") //属性注入值public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +'}';}
}
  1. 新建一个config配置包,编写一个SunConfig配置类
package com.github.subei.config;import com.github.subei.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;// 这个也会Spring容器托管,注册到容器中,因为他本来就是一个@Component
// @Configuration代表这是一个配置类,就和我们之前看的beans.xml
@Configuration  // 代表这是一个配置类
@ComponentScan("com.github.subei.pojo")
public class SunConfig {// 注册一个bean,就相当于我们之前写的一个bean标签;// 这个方法的名字,就相当bean标签中的id属性;// 这个方法的返回值,就相当bean标签中的cLass属性;@Beanpublic User getUser(){return new User(); // 就是返回要注入到bean的对象}
}
  1. 测试类
import com.github.subei.config.SunConfig;
import com.github.subei.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class MyTest {// 如果完全使用了配置类方式去做,我们就只能通过Annotationconfig 上下文来获收容器,通过配置类的class对象加载!public static void main(String[] args) {ApplicationContext applicationContext =new AnnotationConfigApplicationContext(SunConfig.class);User user = (User) applicationContext.getBean("getUser");System.out.println(user.getName());}
}

在这里插入图片描述
导入其它配置类:

package com.github.subei.config;import com.github.subei.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;// 这个也会Spring容器托管,注册到容器中,因为他本来就是一个@Component
// @Configuration代表这是一个配置类,就和我们之前看的beans.xml
@Configuration  // 代表这是一个配置类
@ComponentScan("com.github.subei.pojo")
@Import(SunConfig2.class) // 导入合并其他配置类,类似于配置文件中的 inculde 标签
public class SunConfig {// 注册一个bean,就相当于我们之前写的一个bean标签;// 这个方法的名字,就相当bean标签中的id属性;// 这个方法的返回值,就相当bean标签中的cLass属性;@Beanpublic User getUser(){return new User(); // 就是返回要注入到bean的对象}
}

这种纯ava的配置方式,在SpringBoot中随处可见!

http://www.xdnf.cn/news/971191.html

相关文章:

  • MFC 第一章概述
  • 2025 Java 面试大全
  • 39.第二阶段x64游戏实战-封包-分析计数器
  • gro文件和top文件介绍,以及如何合并两个gro文件或两个top文件
  • 【论文解读】ReSearch:让LLM自主学习搜索
  • Qt进阶开发:动画框架的介绍和使用
  • Zynq multi boot及网口远程更新开发
  • Android Studio 问题:Android Studio 一直开在 Updating indexes
  • 【运维】【期末实训】网站简易搭建模拟
  • 核心机制:面向字节流
  • C++:std::is_convertible
  • <7>-MySQL内置函数
  • Python训练营-Day27-函数专题2:装饰器
  • Java如何权衡是使用无序的数组还是有序的数组
  • copilot基于 DeepSeek-R1 思路构建 VLA 自动驾驶强化学习系统
  • 华为云Flexus+DeepSeek征文|体验华为云ModelArts快速搭建Dify-LLM应用开发平台并创建联网大模型
  • QMC5883L的驱动
  • iview组件库:自定义方法去控制Tree树形数据的根节点与叶节点的关联性
  • Android Studio jetpack compose折叠日历日期选择器【折叠日历】
  • IOC和AOP
  • vue实现气泡词云图
  • FastJson的反序列化问题入门
  • Qt使用ODBC连接MySQL数据库
  • R7-1 显示Pascal三角形
  • 【代码模板】从huggingface加载tokenizer和模型,进行推理
  • idea64.exe.vmoptions配置
  • IDEA中配置HTML和Thymeleaf热部署的步骤
  • 蓝桥杯 2024 15届国赛 A组 儿童节快乐
  • 指针与引用参数传递的区别及内存操作流程详解
  • 分散电站,集中掌控,安科瑞光伏云平台助力企业绿色转型