spring-Bean

这篇具有很好参考价值的文章主要介绍了spring-Bean。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Bean

在 Spring 中,构成应用程序主干并由Spring IoC容器管理的对象称为bean。bean是一个由Spring IoC容器实例化、组装和管理的对象。

基本概念

bean的作用域

概念:在spring中可以通过配置bean标签的scope属性来指定bean的作用域范围。

取值 含义 创建对象的时机
singleton(默认) 在IoC容器中,这个bean的对象始终为单实例 IOC容器初始化
prototype 这个bean在IOC容器中有多个实例 获取bean时

如果在WebApplicationContext环境下还会有另外几个作用域(不常用)

取值 含义
request 在一个请求范围内有效
session 在一个会话范围内有效
测试bean的作用域
singleton

创建Orders对象

public class Orders {

}

编写配置文件

<!--通过scope属性配置单实例或者多实例对象,singleton表示单实例对象 prototype表示多实例-->
<bean id="orders" class="com.louis.scope.Orders" scope="singleton"></bean>

测试

@Test
public void testScope(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-scope.xml");
    Orders orders = applicationContext.getBean("orders", Orders.class);
    logger.info("orders" + orders);
    Orders orders1 = applicationContext.getBean("orders", Orders.class);
    logger.info("orders1" + orders1);
    logger.info("单实例对象判断两次获得的是否相等" + (orders == orders1));
}
/*
* [2023-06-23 15:54:12:661] [INFO] - TestBeanById.testScope(TestBeanById.java:212) - orderscom.louis.scope.Orders@e84a8e1
  [2023-06-23 15:54:12:664] [INFO] - TestBeanById.testScope(TestBeanById.java:214) - orders1com.louis.scope.Orders@e84a8e1
  [2023-06-23 15:54:12:665] [INFO] - TestBeanById.testScope(TestBeanById.java:215) - 单实例对象判断两次获得的是否相等true
* */
prototype

配置文件

<bean id="ordersOther" class="com.louis.scope.Orders" scope="prototype"></bean>

测试

@Test
public void testScopePrototype(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-scope.xml");
    Orders ordersOther = applicationContext.getBean("ordersOther", Orders.class);
    logger.info("ordersOther" + ordersOther);
    Orders ordersOther01 = applicationContext.getBean("ordersOther", Orders.class);
    logger.info("ordersOther01" + ordersOther01);
    logger.info("多实例对象判断两次获得的是否相等" + (ordersOther == ordersOther01));
}

/*
* [2023-06-23 16:01:18:960] [INFO] - TestBeanById.testScopePrototype(TestBeanById.java:228) - ordersOthercom.louis.scope.Orders@2e554a3b
  [2023-06-23 16:01:18:964] [INFO] - TestBeanById.testScopePrototype(TestBeanById.java:230) - ordersOther01com.louis.scope.Orders@3a0d172f
  [2023-06-23 16:01:18:964] [INFO] - TestBeanById.testScopePrototype(TestBeanById.java:231) - 多实例对象判断两次获得的是否相等false
* */

bean的生命周期

1、bean对象创建(调用无参构造方法)
2、给bean对象设置相关属性
3、bean后置处理器(初始化之前)
4、bean对象的初始化操作(调用指定的初始化方法)
5、bean后置处理器(初始化之后)
6、bean对象创建完成,可以使用
7、bean对象销毁(配置指定销毁的方法)
8、IOC容器关闭

测试bean的生命周期
User
package com.louis.beanLife;

/**
 * @author XRY
 * @date 2023年06月23日16:10
 */
public class User {
    private String name;

    public User() {
        System.out.println("1、创建bean对象、调用无参数构造");
    }

    public User(String name) {

        this.name = name;
    }

    //初始化方法
    public void initMethod(){
        System.out.println("4、bean对象初始化,调用指定的初始化方法");
    }

    //销毁方法
    public void destroyedMethod(){
        System.out.println("7、bean对象的销毁,调用指定的销毁的方法");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("2、给bean对象设置属性值");
        this.name = name;
    }
}
编写bean的后置处理器类
public class MyBeanPost implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("3、bean的后置处理器,在初始化之前执行");
        System.out.println(beanName+"::"+bean);
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("5、bean的后置处理器,在初始化之后执行");
        System.out.println(beanName + "::" + bean);
        return 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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
       <bean id="testBeanLife" class="com.louis.beanLife.User" scope="singleton" init-method="initMethod" destroy-method="destroyedMethod">
           <property name="name" value="Louis"></property>
       </bean>
    <!--bean的后置处理器要放入IOC容器中才会生效-->
    <bean id="myBeanPost" class="com.louis.beanLife.MyBeanPost"></bean>
</beans>
测试
@Test
public void testBeanLife(){
    //当需要销毁的时候,我们需要创建ClassPathXmlApplicationContext对象,Application对象中没有相关的销毁方法
    ClassPathXmlApplicationContext applicationContext = new
            ClassPathXmlApplicationContext("bean-life.xml");
    User user = applicationContext.getBean("testBeanLife", User.class);
    System.out.println("6、bean对象创建完成,可以使用");
    logger.info("user" + user);
    applicationContext.close();
}

/*
1、创建bean对象、调用无参数构造
2、给bean对象设置属性值
3、bean的后置处理器,在初始化之前执行
testBeanLife::User{name='Louis'}
4、bean对象初始化,调用指定的初始化方法
5、bean的后置处理器,在初始化之后执行
testBeanLife::User{name='Louis'}
6、bean对象创建完成,可以使用
[2023-06-23 16:47:46:915] [INFO] - TestBeanById.testBeanLife(TestBeanById.java:247) - userUser{name='Louis'}
7、bean对象的销毁,调用指定的销毁的方法
* */

FactoryBean

简介

FactoryBean是Spring提供的一种整合第三方框架的常用机制,它和普通的bean不相同,配置一个FactoryBean类型的bean,在获取bean的时候得到的并不是一class属性中配置的这个类的对象,而是getObject()方法的返回值。通过这种机制,Spring可以帮我们把复杂组件创建的详细过程和繁琐细节屏蔽起来,只展示最简洁的使用界面。

使用步骤

1、创建实体类

使用上面的实体类User

2、创建类MyFactoryBean并实现接口
package com.louis.factorybean;

import org.springframework.beans.factory.FactoryBean;

/**
 * @author XRY
 * @date 2023年06月25日8:49
 */
public class MyFactoryBean implements FactoryBean<User> {
    @Override
    public User getObject() throws Exception {
        return new User();
    }

    @Override
    public Class<?> getObjectType() {
        return User.class;
    }
}
3、编写配置文件
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">
        <bean id="myFactoryBean" class="com.louis.factorybean.MyFactoryBean"></bean>
</beans>
4、测试
@Test
public void testMyFactoryBean(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-factorybean.xml");
    logger.info("myFactoryBean" + applicationContext.getBean("myFactoryBean"));
}
/*[2023-06-25 09:02:09:063] [INFO] - TestBeanById.testMyFactoryBean(TestBeanById.java:266) - myFactoryBeancom.louis.factorybean.User@5ee2b6f9\n*/

Bean管理

基于xml自动装配

根据指定的策略,在IOC容器中匹配某一个bean,自动为指定的备案中所依赖的类类型或接口类型属性赋值

示例
1、准备

创建controller、service和dao层,编写它们的接口和实现类,在controller中定义service类型的属性,生成属性的set方法,在service定义dao类型属性并生成set方法。

controler

public class UserController {
    private UserService userService;
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public void addUser(){
        System.out.println("我是controller");
        //调用service的方法
        userService.addUserService();
        //原始方法:Controller调用service
//        UserService userService = new UserServiceImpl();
//        userService.addUserService();
    }
}

service

public interface UserService {
    public void addUserService();
}

impl

public class UserServiceImpl implements UserService {
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    @Override
    public void addUserService() {
        System.out.println("我是UserService");
        //调用方法实现
        userDao.addUserDao();
        //原始方法调用实现
//        UserDao userDao = new UserDaoImpl();
//        userDao.addUserDao();
    }
}

dao

public interface UserDao {
    public void addUserDao();
}

daoimpl

public class UserDaoImpl implements UserDao {

    @Override
    public void addUserDao() {
        System.out.println("我是UserDao");
    }
}
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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="controller" class="com.louis.autoFill.controller.UserController"
          autowire="byType"></bean>
    <bean id="service" class="com.louis.autoFill.service.impl.UserServiceImpl"
          autowire="byType"></bean>
    <bean id="dao" class="com.louis.autoFill.dao.impl.UserDaoImpl"
    ></bean>
</beans>
3、测试
@Test
public void testAutoFill(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-auto.xml");
    UserController controller = applicationContext.getBean("controller", UserController.class);
    controller.addUser();
}

/*我是controller
我是UserService
我是UserDao
*/
使用细节:

使用bean标签的autowire属性设置自动装配效果,

自动装配方式byType
<bean id="controller" class="com.louis.autoFill.controller.UserController"
      autowire="byType"></bean>
<bean id="service" class="com.louis.autoFill.service.impl.UserServiceImpl"
      autowire="byType"></bean>
<bean id="userDao" class="com.louis.autoFill.dao.impl.UserDaoImpl"
></bean>

byType:表示根据类型匹配IOC容器中的某个兼容类型的bean,为属性自动赋值

若IOC中没有任何一个兼容类型的bean能够为属性赋值,则该属性不装配,值为默认值null
若在IOC中,有多个兼容类型的bean能够为属性赋值,则抛出NoUniqueBeanDefinitionException

自动装配byName
<bean id="controller" class="com.louis.autoFill.controller.UserController"
      autowire="byName"></bean>
<bean id="userService" class="com.louis.autoFill.service.impl.UserServiceImpl"
      autowire="byName"></bean>
<bean id="userDao" class="com.louis.autoFill.dao.impl.UserDaoImpl"
></bean>

byName:将自动装配的属性的属性名,作为bean的id在IOC容器中匹配相对应的bean进行赋值
需要注意的是属性的名称和id的名称必须保持一致

基于注解方式

从java5开始,java增加了对注解(Annotation)的支持,它是代码中的一种特殊标记,可以在编译、类加载和运行时被读取,执行相应的处理。开发人员可以通过注解在不改变原有代码的和逻辑的情况下,在代码中嵌入补充信息。我们可以使用注解来实现自动装配,简化Spring的xml配置。

格式@注解名称(属性1=属性值…),它可以使用在类、属性和方法上面。

步骤:
1、引入Spring依赖
2、开启组件扫描

spring默认不适用注解装配bean,因此我们需要在spring的xml配置中,通过context:component-scan元素开启spring beans的自动扫描功能,开启后,spring会自动扫描指定的包(base-package属性设置)及其子包下的所有类,如果使用了@Component注解,就将该类装配到容器中。在使用context:component-scan元素开启自动扫描功能前,首先要在xml配置的一级标签<beans>中添加context相关的约束。

<?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/context  
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--开启组件扫描-->
    <context:component-scan base-package="com.louis"></context:component-scan>
</beans>
组件扫描的方式

①最基本方式

<context:component-scan base-package="com.louis"></context:component-scan>

②指定要排除的组件

<context:component-scan base-package="com.louis">
    <!--context:exclude-filter标签指定排除规则-->
    <!--
    type:设置排除或包含的依据
    type="annotation",根据注解排除,expression中设置要排除的注解的全类名
    type="assignable",根据类型排除,expression中设置要排除的类型的的全类名
    -->
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

③仅扫描指定组件

<context:component-scan base-package="com.louis">
    <!--context:include-filter标签指定在原有扫描规则的基础上追加的规则-->
    <!--
    type:设置排除或包含的依据
    -->
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
3、使用注解定义bean

spring提供了多个注解,这些注解可以直接标注在java类上,将他们定义成Spring Bean。

@Component(value="user")//相当于<bean id="user" class="..."></bean>,其中value可以不写,在不屑的时候就是默认类的首字母小写
//@Repository(value="user")
//@Service(value="user")
//@Controller(value="user")
public class User {
    public void testUser(){
        System.out.println("我是User类");
    }
}
注解 说明
@component 该注解用于描述Spring中的Bean,它是一个泛化的概念,仅仅表示容器中的一个组件(bean),并且可以作用在应用的任何层次,例如:service层、dao层等,使用时,只需要将该类注解标注在相应类上即可。
@Repository 该注解用于将数据访问层(Dao层)的类标识为Spring中的Bean,其功能与@Component相同
@Service 该注解通常作用在业务层(Service层),用于将业务层的类标识为Spring中的Bean,其功能与@Component相同
@Controller 该注解通常作用在控制层(如SpringMVC的Controller),用于将控制层的类标识为Spring中的Bean,其功能与@Component相同。
4、依赖注入
@AutoWired注入

单独使用@AutoWired注解,默认根据类型装配(默认时byType)
它可以使用在构造方法、方法、形参、属性和注解上。该注解有一个required属性,默认值是true,表示注入的时候要求被注入的bean必须是存在的,如果不存在则会报错,如果required属性设置为false,表示注入的Bean存在或者不存在都没有关系。

第一种方式:属性注入

@Autowired //会根据类型找到对应的对象,完成注入
private UserDao userDao;

第二种方式:set注入

private UserService userService;
@Autowired
public void setUserService(UserService userService) {
    this.userService = userService;
}

第三种方式:构造方法注入

private UserService userService;

@Autowired
public UserController(UserService userService) {
    this.userService = userService;
}

第四种方式:形参上进行注入

private UserService userService;

public UserController(@Autowired UserService userService) {
    this.userService = userService;
}

第五种方式:只有一个构造函数,可以不使用注解

private UserService userService;

public UserController(UserService userService) {
    this.userService = userService;
}

第六种方式:@Autowired注解和@Qualifier注解联合使用

@Autowired默认是根据类型进行匹配,@Qualifier则默认是根据名称进行匹配,可以用于注入有多个实现类的情况。

@Autowired
@Qualifier(value = "userDaoOtherImpl")
private UserDao userDao;

@Resource注入

@Resource注解也可以完成属性注入,他和@Autowired的区别:

@Resource注解时JDK扩展包中的,属于JDK的一部分。所以该注解是标准注解,更加具有通用性。
@Autowired注解是Spring框架自己的
@Resource注解默认根据名称装配byName,未指定name时,使用属性名作为name.通过name找不到的话会自动启动通过来行byType装配
@Autowired注解默认根据类型装配byType,如果象根据名称装配,需要配合@Qulifier注解一起使用
@Resource注解用在属性、set方法上
@Autowired注解用在属性、set方法、构造方法、构造方法形参上。

@Resource注解属于JDK扩展包,所以不再JDK中,需要额外引入以下依赖文章来源地址https://www.toymoban.com/news/detail-576374.html

<dependency>
  <groupId>jakarta.annotation</groupId>
  <artifactId>jakarta.annotation-api</artifactId>
  <version>2.1.1</version>
</dependency>

到了这里,关于spring-Bean的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JAVA后端开发面试基础知识(八)——Spring

    Spring是一个轻量级Java开发框架 我们一般说 Spring 框架指的都是 Spring Framework,它是很多模块的集合,使用这些模块可以很方便地协助我们进行开发,比如说 Spring 支持 IoC(Inverse of Control:控制反转) 和 AOP(Aspect-Oriented Programming:面向切面编程)、可以很方便地对数据库进行访问、

    2024年03月10日
    浏览(72)
  • 微信小程序的授权登录-Java 后端 (Spring boot)

    微信开发文档链接:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html 一个可以测试的微信小程序 此微信小程序的APPID和APPscret(至开发者后台获取) 从时序图我们可以了解到流程大致分为两步: 小程序端获取code后传给Java后台 Java后台获取code后向微信后台接口

    2024年02月09日
    浏览(51)
  • “从零开始学习Spring Boot:快速搭建Java后端开发环境“

    标题:从零开始学习Spring Boot:快速搭建Java后端开发环境 摘要:本文将介绍如何从零开始学习Spring Boot,并详细讲解如何快速搭建Java后端开发环境。通过本文的指导,您将能够快速搭建一个基于Spring Boot的Java后端开发环境并开始编写代码。 正文: 一、准备工作 在开始之前,

    2024年02月15日
    浏览(55)
  • Spring bean定义&Spring Bean 的作用域

    目录 Spring bean定义   Spring配置元数据 Spring Bean 的作用域   singleton作用域:   原型作用域: 示例:   形成应用程序的骨干是由Spring IoC容器所管理的对象称为bean。bean被实例化,组装,并通过Spring IoC容器所管理的对象。这些bean由容器提供,例如,在XML的bean/定义,已经看到了

    2024年02月08日
    浏览(42)
  • Spring | Spring中的Bean (上)

    Spring 可以被看作是个一个 大型工厂 , 这个工厂的 作用 就是 生产和管理Sping容器中的Bean 。如果想要在项目中使用这个工厂,就需要开发者对Spring的 配置文件 进行 配置 。 Spring容器 支持 XML 和 Properties 两种格式的 配置文件 ,在实际开发中, 最常使用 的就是 XML格式 的配置

    2024年01月17日
    浏览(97)
  • Spring | Spring中的Bean--下

    Spring容器 可以管理 singleton作用域 的 Bean 的 生命周期 ,在此作用域下, Spring能够精确地知道 该Bean 何时被创建 , 何时初始化完成 以及 何时被销毁 。 对于 prototype作用域 的 Bean ,Spring 只负责创建 ,当容器创建了Bean实例后,Bean的实例就交给客户端代码来管理, Spring容器将

    2024年01月18日
    浏览(37)
  • Spring | Spring中的Bean--上

    Spring 可以被看作是个一个 大型工厂 , 这个工厂的 作用 就是 生产和管理Sping容器中的Bean 。如果想要在项目中使用这个工厂,就需要开发者对Spring的 配置文件 进行 配置 。 Spring容器 支持 XML 和 Properties 两种格式的 配置文件 ,在实际开发中, 最常使用 的就是 XML格式 的配置

    2024年01月22日
    浏览(39)
  • 【spring】spring bean的生命周期

    spring bean的生命周期 简介 本文测试并且介绍了spring中bean的生命周期,如果只想知道结果可以跳到最后一部分直接查看。 一、bean的创建阶段 spring中的bean是何时创建的? 在spring中有一个非常重要的注解,叫做**@Scope**,这个注解是用来控制spring中的bean是否是单例的,一般情况

    2024年02月15日
    浏览(50)
  • 【Spring】-Spring中Bean对象的存取

    作者 :学Java的冬瓜 博客主页 :☀冬瓜的主页🌙 专栏 :【Framework】 主要内容 :往spring中存储Bean对象的三大方式:XML方式(Bean标签);五大类注解;方法注解。从spring中取对象的两种方式:基本方法、注解方法(属性注入、set注入、构造方法注入)。 在Spring中,Bean的装配方式

    2024年02月12日
    浏览(30)
  • Spring整理-Spring Bean的生命周期

    Spring Bean的生命周期涉及多个阶段,从Bean的定义到其销毁。在这个过程中,Spring容器负责创建、初始化、使用和最终销毁Bean。了解这个生命周期有助于更好地管理Bean的行为和资源使用。 实例化(Instantiation): 容器首先创建Bean的实例。 填充属性(Populate Properties): 容器

    2024年01月21日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包