Spring容器

news2024/11/15 17:45:45

1. Spring核心容器介绍

问题:按照Bean名称获取Bean有什么弊端,按照Bean类型获取Bean有什么弊端?

1.1 创建容器

  • 方式一:类路径加载配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
  • 方式二:文件路径加载配置文件
ApplicationContext ctx = new FileSystemXmlApplicationContext("D:\\applicationContext.xml");
  • 加载多个配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean1.xml", "bean2.xml");

1.2 获取bean对象

  • 方式一:使用bean名称获取

弊端:需要自己强制类型转换

BookDao bookDao = (BookDao) ctx.getBean("bookDao");
  • 方式二:使用bean名称获取并指定类型
BookDao bookDao = ctx.getBean("bookDao", BookDao.class);
  • 方式三:使用bean类型获取

弊端:如果IOC容器中同类型的Bean对象有多个,此处获取会报错

BookDao bookDao = ctx.getBean(BookDao.class);

1.3 容器类层次结构

1.4 BeanFactory

  • 类路径加载配置文件
Resource resources = new ClassPathResource("applicationContext.xml");
BeanFactory bf = new XmlBeanFactory(resources);
BookDao bookDao = bf.getBean("bookDao", BookDao.class);
bookDao.save();
  • BeanFactory创建完毕后,所有的Bean均为延迟加载,也就是说我们调用getBean()方法获取Bean对象时才创建Bean对象并返回给我们

2. Spring核心容器总结

2.1 容器相关

  • BeanFactory是IoC容器的顶层接口,初始化BeanFactory对象时,加载的bean延迟加载

  • ApplicationContext接口是Spring容器的核心接口,初始化时bean立即加载

  • ApplicationContext接口提供基础的bean操作相关方法,通过其他接口扩展其功能

  • ApplicationContext接口常用初始化类

    • ClassPathXmlApplicationContext(常用)

    • FileSystemXmlApplicationContext

2.2 bean相关

<bean id="cartDao"                                          bean的Id
      name="dao cartDaoImpl"                                bean的别名
      class="com.by.dao.impl.CartDaoImpl"               bean类型,静态工厂类,FactoryBean类
      scope="singleton"                                 控制bean的实例数量
      init-method="init"                                生命周期初始化方法
      destroy-method="destory"                          生命周期销毁方法
      autowire="byType"                                 自动装配类型
      factory-method="getOrderDao"                      bean工厂方法,应用于静态工厂或实例工厂
      factory-bean="com.by.dao.OrderDaoFactory"         实例工厂bean
      lazy-init="true">                                 控制bean延迟加载
    
</bean>

2.3 依赖注入相关

<bean id="orderDao" class="com.by.dao.impl.OrderDaoImpl">
    <constructor-arg name="cartDao" ref="cartDao"/>                 构造器注入引用类型
    <constructor-arg name="orderDao" ref="orderDao"/>               
    <constructor-arg name="msg" ref="WARN"/>                        构造器注入简单类型
    <constructor-arg type="java.lang.String" index="3" value="WARN"/>类型匹配与索引匹配
    <property name="cartDao" value="cartDao"/>                      setter注入引用类型
    <property name="orderDao" value="orderDao"/>
    <property name="msg" value="WARN"/>                             setter注入简单类型
    <property name="names">                                         setter注入集合类型
        <list>                                                      list集合
            <value>second</value>                                   集合注入简单类型    
            <ref bean="dataSource"></ref>                           集合注入引用类型
        </list>
    </property>
​
</bean>

3. Spring注解开发

3.1 注解开发定义Bean对象【重点】

xml配置Bean对象有些繁琐,使用注解简化Bean对象的定义

问题1:使用什么标签进行Spring注解包扫描?

问题2:@Component注解和@Controller、@Service、@Repository三个衍生注解有什么区别?

3.2 基本使用

【第一步】在applicationContext.xml中开启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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd"><!--开启注解扫描 扫描com.by及其子包下所有的类-->
<context:component-scan base-package="com.by"/>
</beans>

【第二步】在类上使用@Component注解定义Bean。

//@Component定义bean
@Component("orderDao")
public class OrderDaoImpl implements OrderDao {
    @Override
    public void save() {
        System.out.println("order dao save...");
    }
}
@Component
public class OrderServiceImpl implements OrderService {
   private OrderDao orderDao;public void setOrderDao(OrderDao orderDao) {
        this.orderDao = orderDao;
    }@Override
    public void add() {
        System.out.println("order service save ...");
        orderDao.save();
    }
}

如果@Component注解没有使用参数指定Bean的名称,那么类名首字母小写就是Bean在IOC容器中的默认名称。
例如:OrderServiceImpl对象在IOC容器中的名称是orderServiceImpl。

【第三步】在测试类中获取Bean对象

 @Test
    public void ComponentTest(){
        ApplicationContext ac=new ClassPathXmlApplicationContext("application.xml");
        OrderDao orderDao=(OrderDao) ac.getBean("orderDao");
        System.out.println(orderDao);
        //按类型匹配bean
        OrderService orderService=ac.getBean(OrderService.class);
        System.out.println(orderService);
    }
}

注意:在测试类中不要调用orderService的save方法,因为还没有给OrderServiceimpl中的bookDao赋值,
调用orderService的save方法会出现空指针异常。

3.3 @Component三个衍生注解

加粗的注解为常用注解

  • Spring提供@Component注解的三个衍生注解

    • @Controller:用于表现层bean定义

    • @Service:用于业务层bean定义

    • @Repository:用于数据层bean定义

@Service("cartDao")
public class CartDaoImpl implements CartDao {
   
}
@Repository
public class OrderServiceImpl implements OrderService {
}

3.4 纯注解开发模式【重点】

问题1:配置类上使用什么注解表示该类是一个配置类?

问题2:配置类上使用什么注解进行Spring注解包扫描?

3.4.1纯注解开发模式介绍

  • Spring3.0开启了纯注解开发模式,使用Java类替代配置文件,开启了Spring快速开发赛道

  • Java类代替Spring核心配置文件

<!--开启注解扫描 扫描com.by及其子包下所有的类-->
<context:component-scan base-package="com.by"/>
    相当于
@Configuration
@ComponentScan("com.by")
public class SpringConfig{
}
  • @Configuration注解用于设定当前类为配置类

  • @ComponentScan注解用于设定扫描路径,此注解只能添加一次,多个数据请用数组格式

@ComponentScan({com.by.service","com.by.dao"})
  • 读取Spring核心配置文件初始化容器对象切换为读取Java配置类初始化容器对象
//加载配置文件初始化容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
切换为下面
//加载配置类初始化容器
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);

3.4.2 代码演示

【第一步】定义配置类代替配置文件

//声明当前类为Spring配置类
@Configuration
//Spring注解扫描,相当于<context:component-scan base-package="com.by"/>
@ComponentScan("com.by")
//设置bean扫描路径,多个路径书写为字符串数组格式
//@ComponentScan({"com.by.service","com.by.dao"})
public class SpringConfig {
}

【第二步】在测试类中加载配置类,获取Bean对象并使用

 @Test
    public void AppForAnnotaion(){
        ApplicationContext ac=new AnnotationConfigApplicationContext(SpringConfig.class);
        OrderDao orderDao=(OrderDao) ac.getBean("orderDao");
        System.out.println(orderDao);
        //按类型匹配bean
        OrderService orderService=ac.getBean(OrderService.class);
        System.out.println(orderService);
    }

3.4.3 注解开发Bean作用范围和生命周期管理

在类上使用什么注解定义Bean的作用范围?

1. bean作用范围注解配置

  • 使用@Scope定义bean作用范围
@Repository
@Scope("singleton")
public class BookDaoImpl implements BookDao {
}

2. bean生命周期注解配置

  • 使用@PostConstruct、@PreDestroy定义bean生命周期
@Repository
@Scope("singleton")
public class BookDaoImpl implements BookDao {
    public BookDaoImpl() {
        System.out.println("book dao constructor ...");
    }
    @PostConstruct
    public void init(){
        System.out.println("book init ...");
    }
    @PreDestroy
    public void destroy(){
        System.out.println("book destory ...");
    }
}

注意:@PostConstruct和@PreDestroy注解是jdk中提供的注解,从jdk8开始,jdk中的javax.annotation包被移除了,也就是说这两个注解就用不了了,可以额外导入一下依赖解决这个问题。

<dependency>
  <groupId>javax.annotation</groupId>
  <artifactId>javax.annotation-api</artifactId>
  <version>1.3.2</version>
</dependency>

4. 注解开发依赖注入【重点】

问题1:请描述@Autowired注解是如何进行自动装配的?

问题2:请描述@Qualifier注解的作用

4.1 使用@Autowired注解开启自动装配模式(按类型)

@Service
public class BookServiceImpl implements BookService {
    //@Autowired:注入引用类型,自动装配模式,默认按类型装配
    @Autowired
    private BookDao bookDao;public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}

不管是使用配置文件还是配置类,都必须进行对应的Spring注解包扫描才可以使用。
@Autowired默认按照类型自动装配,如果IOC容器中同类的Bean有多个,那么默认按照变量名和Bean的名称匹配,建议使用@Qualifier注解指定要装配的bean名称

注意:自动装配基于反射设计创建对象并暴力反射对应属性为私有属性初始化数据,因此无需提供setter方法。

4.2 使用@Qualifier注解指定要装配的bean名称

解决IOC容器中同类型Bean有多个装配哪一个的问题

@Service
public class BookServiceImpl implements BookService {
    //@Autowired:注入引用类型,自动装配模式,默认按类型装配
    @Autowired
    //@Qualifier:自动装配bean时按bean名称装配
    @Qualifier("bookDaoImpl")
    //单独使用和@Qualifier+@Autowired 一样 主要是根据名称注入
    @Resource(name="bookDao")
    private BookDao bookDao;public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}

注意:@Qualifier注解无法单独使用,必须配合@Autowired注解使用

4.3 使用@Value实现简单类型注入

@Repository("bookDao")
public class BookDaoImpl implements BookDao {
    //@Value:注入简单类型(无需提供set方法)
    @Value("${name}")
    private String name;public void save() {
        System.out.println("book dao save ..." + name);
    }
}

以上@Value注解中使用${name}从属性文件中读取name值,
那么就需要在配置类或者配置文件中加载属性文件。

@Configuration
@ComponentScan("com.by")
//@PropertySource加载properties配置文件
@PropertySource({"classpath:jdbc.properties"}) //{}可以省略不写
public class SpringConfig {
}

注意:@PropertySource()中加载多文件请使用数组格式配置,
不允许使用通配符*

5. 注解开发管理第三方Bean【重点】

导入自己定义的配置类有几种方式?

类型描述
名称bean
类型方法注解
所属位置方法定义上方
功能设置该方法的返回值作为Spring管理的bean
  • 说明:

    • 因为第三方bean无法在其源码上进行修改,使用@Bean解决第三方bean的引入问题

    • 该注解用于替换xml配置的静态工厂和实例工厂创建bean,不区分方法是否为静态或非静态

    • @Bean所在的类必须被spring扫描加载,否则该注解无法生效

  • 相关属性

    • value(默认):定义bean的访问id

【第一步】单独定义配置类

public class JdbcConfig {
    //@Bean:表示当前方法的返回值是一个bean对象,添加到IOC容器中
    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost:3306/springdb");
        ds.setUsername("root");
        ds.setPassword("12345");
        return ds;
    }
}

【第二步】将独立的配置类加入核心配置

类型描述
名称import
类型类注解
所属位置类定义上方
功能导入第三方bean作为Spring控制的资源

说明:

  • @Import注解在同一个类上,仅允许添加一次,如果需要导入多个,使用数组的形式进行设定

  • 在被导入的类中可以继续使用@Import导入其他资源

  • @bean所在的类可以使用导入的形式进入spring容器无需声明为bean

方式1:@Import注解导入式

@Configuration
@ComponentScan("com.by")
//@Import:导入配置信息
@Import({JdbcConfig.class})
public class SpringConfig {
}

方式2:@ComponentScan扫描式

@Configuration
@ComponentScan({"com.by.config","com.by.service","com.by.dao"})  //只要com.by.config包扫到了就行,三个包可以合并写成com.by
public class SpringConfig {
}

测试:

DataSource dataSource = (DataSource) ac.getBean("dataSource");
System.out.println(dataSource);

6. 注解开发为第三方Bean注入资源【重点】

配置类中如何注入简单类型数据,如何注入引用类型数据?

6.1 简单类型依赖注入

public class JdbcConfig {
    //1.定义一个方法获得要管理的对象
    @Value("com.mysql.jdbc.Driver")
    private String driver;
    @Value("jdbc:mysql://localhost:3306/springdb")
    private String url;
    @Value("root")
    private String userName;
    @Value("12345")
    private String password;
    //2.@Bean:表示当前方法的返回值是一个bean对象,添加到IOC容器中
    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driver);
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        return ds;
    }
}

如果@Value()中使用了EL表达式读取properties属性文件中的内容,那么就需要加载properties属性文件。

6.2 引用类型依赖注入

//Spring会自动从IOC容器中找到BookDao对象赋值给参数bookDao变量,如果没有就会报错。@Bean 
public DataSource dataSource(BookDao bookDao){
    System.out.println(bookDao);
    DruidDataSource ds = new DruidDataSource();
    ds.setDriverClassName(driver);
    ds.setUrl(url);
    ds.setUsername(userName);
    ds.setPassword(password);
    return ds;
}

引用类型注入只需要为bean定义方法设置形参即可,容器会根据类型自动装配对象

7. 注解开发总结

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/712309.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

14. 向用户推荐朋友收藏的商品

文章目录 题目需求思路一&#xff1a;使用 Except实现一实现二&#xff1a;使用 Except思路三&#xff1a;使用 full outer join where实现三实现四&#xff1a;使用 not in concat题目来源 题目需求 现请向所有用户推荐其朋友收藏但是用户自己未收藏的商品&#xff0c;请从…

阻抗计算,真的没有那么难!

问&#xff1a;什么是阻抗&#xff1f; 答&#xff1a;在具有电阻、电感和电容的电路里&#xff0c;对电路中的电流所起的阻碍作用叫做阻抗。 问&#xff1a;什么是阻抗匹配? 答&#xff1a;阻抗匹配是指信号源或者传输线跟负载之间达到一种适合的搭配。阻抗匹配主要有两点作用…

ubuntu git clone 失败

命令行报错如下&#xff1a; gitxxx.xx.com: Permission denied (publickey). fatal: 无法读取远程仓库。修改步骤&#xff1a; 1、.ssh权限配置问题 .ssh 文件夹权限 755 或 700 config 文件权限 644 id_rsa 文件权限 600 id_rsa.pub 文件权限 644 r&#xff1a;read 代表读…

VMware安装Centos7并初始化网络使外部可以访问

本文目录 1&#xff1a;下载镜像2&#xff1a;安装centos7虚拟机2.1:初始化虚拟机2.2 初始化系统2.3 修改虚拟机网络模式 3&#xff1a;配置VMware虚拟网络编辑器4&#xff1a;配置centos网络4.1 修改网络配置文件4.2 刷新网络配置 5 验证网络总结 1&#xff1a;下载镜像 进入…

Web3.0在互联网圈爆红,这个“新一轮”概念有哪些机会?

在互联网行业里&#xff0c;新概念和潮流层出不穷&#xff0c;每一个概念都伴随着一轮火热的讨论和关注。从区块链到元宇宙&#xff0c;互联网的发展一直在不断地推动着新的创新和变革。而如今&#xff0c;Web3.0 成为了最新的热点话题&#xff0c;引起了互联网、科技和金融领域…

vue_前后端分离-增删改操作

增加操作和修改操作: 两个操作放一个页面进行操作 使用插槽(scope.row)的方式获取列表中的每一行数据 <template slot-scope"scope"><el-buttonsize"mini"click"openEditDialog( scope.row)">编辑</el-button>在进行添加的…

迅为RK3568开发板Buildroot 系统自启动 QT 程序

本小节将讲解如何开机自启动 QT 程序。 在设置自启动 QT 程序之前&#xff0c;首先要编译好 QT 可执行程序&#xff0c;完成以下两步。 1、 已经根据 03_【北京迅为】itop-3568 开发板快速使用编译环境 ubuntu18.04 v1.0.doc 第 10 章节进行了 QT 程序的交叉编译 2、 将交叉…

华为OD机试真题B卷 Python 实现【内存资源分配】,附详细解题思路

目录 一、题目描述二、输入描述三、输出描述四、解题思路五、Python算法源码六、效果展示1、输入2、输出 3、说明4、如果改一下呢&#xff1f; 一、题目描述 有一个简易内存池&#xff0c;内存按照大小粒度分类&#xff0c;每个粒度有若干个可用内存资源&#xff0c;用户会进行…

django 使用channels 搭建websocket聊天程序

channels官方文档&#xff1a;Django Channels — Channels 4.0.0 documentation 效果如下&#xff1a; 主要实现功能 基于Django的认证的群聊 具体实现 当建立websocket的时候&#xff0c;建立之前是http消息&#xff0c;我们可以拿到http消息里面的cookie等信息进行认证&…

数字经济时代,高校该如何建设大数据实验实训室,培养高质量数智人才?

数智人才作为数字经济时代发展的重要支撑资源&#xff0c;人才质量、存量与储备量之争&#xff0c;成为综合国力和区位竞争的重要内容&#xff0c;而大数据与人工智能技术作为数字经济的主要驱动力&#xff0c;相关人才的培养尤其重要。教育部自2016年起&#xff0c;陆续批准设…

Maven中 排除依赖 exclusions

使用maven进行jar包依赖管理时&#xff0c;maven会自行管理jar包及其依赖链条&#xff0c;但往往会遇到依赖冲突问题&#xff0c;这时候就可以尝试使用exclusions来进行依赖管理 demo:排除tomcat 启用 jetty <dependency><groupId>org.springframework.boot</g…

map父子维护的ebom父子部件关系计算组套数量

map父子维护的ebom父子部件关系计算组套数量 使用ebom时候&#xff0c;把部件父子关系和安装数量维护在了map上面&#xff0c;要计算组套数量&#xff0c;需要递归从当前往上取出父级安装数量相乘&#xff0c;一直取到最顶层。 G的组套数量&#xff1a;GDB32212 E的组套数量&a…

如何提高应用的用户留存

用户的留存率是我们应用内最重要的指标之一&#xff0c;是指有多少人在一段时间后还在使用该应用&#xff0c;它定义了我们的受众规模&#xff0c;让我们知道应用是否有增长的能力。 提高应用保留率的策略&#xff1a;1&#xff0c;推送通知&#xff0c;在适当的时候发送推送通…

计算机网络速成

更好的阅读体验 \color{red}{\huge{更好的阅读体验}} 更好的阅读体验 因特网概述 网络、互联网和因特网 网络&#xff1a;将多个计算机或计算机网络通过通信线路连接起来&#xff0c;使得它们可以相互通信和交换信息的系统。由若干节点&#xff08;Node&#xff09;和连接这些…

LInux:生成崩溃程序的core文件

core文件是linux系统下一种记录软件异常的机制&#xff0c;在进程运行崩溃时&#xff0c;系统会将coredump信息写入core文件。 这样就方便我们定位软件问题。 1. 设置core文件大小 使用ulimit -c可以查看当前core文件的大小 默认情况下&#xff0c;core文件的大小为0&#xf…

chatgpt赋能python:Python开发的SEO应用

Python开发的SEO应用 搜索引擎优化&#xff08;SEO&#xff09;已经成为每个网站所有者需要考虑的重要因素之一。随着搜索引擎算法的不断变化和演进&#xff0c;我们需要确保我们的网站能在各种搜索引擎中进行良好的排名。Python作为一门强大的编程语言&#xff0c;已经被广泛…

Databend v1.2 版本发布!Data + AI

各位社区小伙伴们&#xff0c;Databend 于 2023 年 6 月 29 日迎来了 v1.2.0 版本的正式发布&#xff01;相较于 v1.1.0 版本&#xff0c;开发者们一共新增了 600 次 commit&#xff0c;涉及 3083 个文件变更&#xff0c;约 17 万 行代码修改。感谢各位社区伙伴的参与&#xff…

跨境电商如何快速提升产品排名和转化率,打造爆款产品

中小卖家在跨境电商平台上经营时&#xff0c;经常会遇到提升销售瓶颈的问题。今天陈哥将分享一个快速打造爆款的方法&#xff0c;除了SEO优化&#xff08;关键词分析、优化标题、图片、产品描述和定价&#xff09;等方面的策略。同时&#xff0c;测评也是一个有效的手段&#x…

规则引擎是什么,常见的应用领域,你知道吗?

规则引擎是什么 规则引擎&#xff0c;规则引擎是企业数字化转型升级过程中非常必要的软件工具&#xff0c;是一种能够自动执行一定条件下的预设逻辑的技术&#xff0c;可以帮助企业在收到数据或事件时自动触发相关业务规则&#xff0c;其主要优势如下&#xff1a; 易于维护与…

2023年华中杯数学建模C题空气质量预测与预警解题全过程文档及程序

2023年华中杯数学建模 C题 空气质量预测与预警 原题再现 空气污染对人类健康、生态环境、社会经济造成危害&#xff0c;其污染水平受诸多因素的影响&#xff0c;如 PM2.5、PM10、CO、气温、风速、降水量等&#xff0c;探究 PM2.5 等污染物浓度的因素&#xff0c;更精准的预测…