Java Bean的作用域,生命周期和注解

网友投稿 294 2022-11-26

Java Bean的作用域,生命周期和注解

目录Bean的作用域singleton作用域Bean的生命周期1.创建Bean的实现类2.配置Bean3.测试生命周期Bean的装配方式基于XML配置的装配基于注解的装配1.@Component2.@Repository3.@Service4.@Controller5.@Autowired6.@Resource7.@Qualifier总结

Bean的作用域

singleton作用域

当将bean的scope设置为singleton时,Spring IoC容器仅生成和管理一个Bean实例(单例)。使用id或name获取Bean实例时,IoC容器将返回共享的Bean实例。

由于singleton是scope(范围)的默认方式,因此有两种方式将bean的scope设置为singleton。配置文件示例代码如下:

测试singleton作用域,代码如下:

//初始化Spring容器ApplicationContext,加载配置文件

ApplicationContext appCon = new ClassPathXmlApplicationContext("applicationContext.xml");

//测试构造方法实例化Bean

BeanClass b1 = (BeanClass)appCon.getBean("constructorInstance");

System.out.println(b1);

BeanClass b2 = (BeanClass)appCon.getBean("constructorInstance");

System.out.println(b2);

prototype作用域

当bean的scope设置为prototype(原型)时,Spring IoC容器将为每次请求创建一个新的实例。如果将3.3.1中bean的配置修改如下:

Bean的生命周期

Bean的生命周期整个过程如下:

1.根据Bean的配置情况,实例化一个Bean。

2.根据Spring上下文对实例化的Bean进行依赖注入,即对Bean的属性进行初始化。

3.如果Bean实现了BeanNameAware接口,将调用它实现的setBeanName(String beanId)方法,此处参数传递的是Spring配置文件中Bean的ID。

4.如果Bean实现了BeanFactoryAware接口,将调用它实现的setBeanFactory()方法,此处参数传递的是当前Spring工厂实例的引用。

5.如果Bean实现了ApplicationContextAware接口,将调用它实现的setApplicationContext(ApplicationContext)方法,此处参数传递的是Spring上下文实例的引用。

6.如果Bean关联了BeanPostProcessor接口,将调用预初始化方法postProcessBeforeInitialization(Object obj, String s)对Bean进行操作。

7.如果Bean实现了InitializingBean接口,将调用afterPropertiesSet()方法。

8.如果Bean在Spring配置文件中配置了init-method属性,将自动调用其配置的初始化方法。

9.如果Bean关联了BeanPostProcessor接口,将调用postProcessAfterInitialization(Object obj, String s)方法,由于是在Bean初始化结束时调用After方法,也可用于内存或缓存技术。

以上工作(1至9)完成以后就可以使用该Bean,由于该Bean的作用域是singleton,所以调用的是同一个Bean实例。

10.当Bean不再需要时,将经过销毁阶段,如果Bean实现了DisposableBean接口,将调用其实现的destroy方法将Spring中的Bean销毁。

11.如果在配置文件中通过destroy-method属性指定了Bean的销毁方法,将调用其配置的销毁方法进行销毁。

1.创建Bean的实现类

package life;

public class BeanLife {

public void initMyself() {

System.out.println(this.getClass().getName() + "执行自定义的初始化方法");

}

public void destroyMyself() {

System.out.println(this.getClass().getName() +"执行自定义的销毁方法");

}

}

2.配置Bean

在Spring配置文件中,使用实现类BeanLife配置一个id为beanLife的Bean。具体代码如下:

3.测试生命周期

在ch3应用的test包中,创建测试类TestLife,具体代码如下:

//初始化Spring容器,加载配置文件

//为了方便演示销毁方法的执行,这里使用ClassPathXmlApplicationContext

//实现类声明容器

ClassPathXmlApplicationContext ctx =

new ClassPathXmlApplicationContext("applicationContext.xml");

System.out.println("获得对象前");

BeanLife blife = (BeanLife)ctx.getBean("beanLife");

System.out.println("获得对象后" + blife);

ctx.close();//关闭容器,销毁Bean对象

Bean的装配方式

Bean的装配可以理解为将Bean依赖注入到Spring容器中,Bean的装配方式即Bean依赖注入的方式。Spring容器支持基于XML配置的装配、基于注解的装配以及自动装配等多种装配方式。本节将主要讲解基于XML配置的装配和基于注解的装配。

基于XML配置的装配

package assemble;

import java.util.List;

import java.util.Map;

import java.util.Set;

public class ComplexUser {

private String uname;

private List hobbyList;

private Map residenceMap;//Map存储键值对

private Set aliasSet;

private String[] array;

//使用构造方法注入,需要提供带参数的构造方法

public ComplexUser(String uname, List hobbyList, Map residenceMap, Set aliasSet,

String[] array) {

super();

this.uname = uname;

this.hobbyList = hobbyList;

this.residenceMap = residenceMap;

this.aliasSet = aliasSet;

this.array = array;

}

//使用setter方法注入,提供默认无参数的构造方法,并为注入的属性提供setter方法

public ComplexUser() {

super();

}

public void setUname(String uname) {

this.uname = uname;

}

public void setHobbyList(List hobbyList) {

this.hobbyList = hobbyList;

}

public void setResidenceMap(Map residenceMap) {

this.residenceMap = residenceMap;

}

public void setAliasSet(Set aliasSet) {

this.aliasSet = aliasSet;

}

public void setArray(String[] array) {

this.array = array;

}

@Override

public String toString() {

return "uname="+uname+";hobbyList="+hobbyList+";residenceMap="+residenceMap+";alisaSet="+aliasSet+";array="+array;

}

}

唱歌

跳舞

篮球

陈恒100

陈恒101

陈恒102

aaaaa

bbbbb

看书

学习Spring

陈恒103

陈恒104

陈恒105

ccccc

ddddd

package test;

import org.springframework.context.ApplicationContext;

import orgCaqEHUXlbl.springframework.context.support.ClassPathXmlApplicationContext;

import assemble.ComplexUser;

public class TestAssemble {

public static void main(String[] args) {

ClassPathXmlApplicationContext appCon=new ClassPathXmlApplicationContext("applicationContext.xml");

ComplexUser u1=(ComplexUser) appCon.getBean("user1");

//构造方法装配测试

System.out.println(u1);

//setter方法装配测试

ComplexUser u2=(ComplexUser) appCon.getBean("user2");

System.out.println(u2);

appCon.close();

}

}

基于注解的装配

1.@Component

该注解是一个泛化的概念,仅仅表示一个组件对象(Bean),可以作用在任何层次上。

(1)创建Bean的实现类

package annotation;

import org.springframework.beans.factory.annotation.Value;

import org.springframework.stereotype.Component;

@Component()

/**相当于@Component("annotationUser")或@Componenthttp://(value = "annotationUser"),annotationUser为Bean的id,默认为首字母小写的类名**/

public class AnnotationUser {

@Value("chenheng")//只注入了简单的值,复杂值的注入目前使用该方式还解决不了

private String uname;

public String getUname() {

return uname;

}

pubCaqEHUXlbllic void setUname(String uname) {

this.uname = uname;

}

@Override

public String toString() {

return "uname="+uname;

}

}

(2)配置注解

现在有了Bean的实现类,但还不能进行测试,因为Spring容器并不知道去哪里扫描Bean对象。需要在配置文件中配置注解,注解配置方式如下:

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xmlns:context="http://springframework.org/schema/context"

xsi:schemaLocation="http://springframework.org/schema/beans

http://springframework.org/schema/beans/spring-beans.xsd

http://springframework.org/schema/context

http://springframework.org/schema/context/spring-context.xsd">

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xmlns:context="http://springframework.org/schema/context"

xsi:schemaLocation="http://springframework.org/schema/beans

http://springframework.org/schema/beans/spring-beans.xsd

http://springframework.org/schema/context

http://springframework.org/schema/context/spring-context.xsd">

(3)测试Bean实例

package test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import annotation.AnnotationUser;

public class TestAnnoation {

public static void main(String[] args) {

ApplicationContext appcon=new ClassPathXmlApplicationContext("annotationContext.xml");

AnnotationUser au=(AnnotationUser) appcon.getBean("annotationUser");

System.out.println(au.getUname());

}

}

2.@Repository

该注解用于将数据访问层(DAO)的类标识为Bean,即注解数据访问层Bean,其功能与@Component()相同。

3.@Service

该注解用于标注一个业务逻辑组件类(Service层),其功能与@Component()相同。

4.@Controller

该注解用于标注一个控制器组件类(Spring MVC的Controller),其功能与@Component()相同。

5.@Autowired

该注解可以对类成员变量、方法及构造方法进行标注,完成自动装配的工作。 通过 @Autowired的使用来消除setter 和getter方法。默认按照Bean的类型进行装配。

6.@Resource

该注解与@Autowired功能一样。区别在于,该注解默认是按照名称来装配注入的,只有当找不到与名称匹配的Bean才会按照类型来装配注入;而@Autowired默认按照Bean的类型进行装配,如果想按照名称来装配注入,则需要结合@Qualifier注解一起使用。

@Resource注解有两个属性:name和type。name属性指定Bean实例名称,即按照名称来装配注入;type属性指定Bean类型,即按照Bean的类型进行装配。

7.@Qualifier

该注解与@Autowired注解配合使用。当@Autowired注解需要按照名称来装配注入,则需要结合该注解一起使用,Bean的实例名称由@Qualifier注解的参数指定。

上面几个注解中,虽然@Repository、@Service和 @Controller等注解的功能与@Component()相同,但为了使标注类的用途更加清晰(层次化),在实际开发中推荐使用@Repository标注数据访问层(DAO层)、使用@Service标注业务逻辑层(Service层)以及使用@Controller标注控制器层(控制层)。

package annotation.dao;

import org.springframework.stereotype.Repository;

@Repository("testDao")

/**相当于@Repository,但如果在service层使用@Resource(name="testDao")的话,testDdao不能省略**/

public class TestDaoImpl implements TestDao {

@Override

public void save() {

// TODO Auto-generated method stub

System.out.println("testDao save");

}

}

package annotation.service;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import annotation.dao.TestDao;

import jakarta.annotation.Resource;

@Service("testService")

public class TestServiceImpl implements TestService {

@Autowired

/**相当于@Autowired.@Autowired默认按照Bean类型装配**/

private TestDao testDao;

@Override

public void save() {

// TODO Auto-generated method stub

testDao.save();

System.out.println("testService save");

}

}

package annotation.controller;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import annotation.service.TestService;

@Controller("testController")

public class TestControllerImpl {

@Autowired

private TestService testService;

public void save() {

// TODO Auto-generated method stub

testService.save();

System.out.println("testController save");

}

}

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xmlns:context="http://springframework.org/schema/context"

xsi:schemaLocation="http://springframework.org/schema/beans

http://springframework.org/schema/beans/spring-beans.xsd

http://springframework.org/schema/context

http://springframework.org/schema/context/spring-context.xsd">

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xmlns:context="http://springframework.org/schema/context"

xsi:schemaLocation="http://springframework.org/schema/beans

http://springframework.org/schema/beans/spring-beans.xsd

http://springframework.org/schema/context

http://springframework.org/schema/context/spring-context.xsd">

package test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import annotation.controller.TestControllerImpl;

public class TestMoreAnnotation {

public static void main(String[] args) {

ApplicationContext appcon=new ClassPathXmlApplicationContext("annotationContext.xml");

TestControllerImpl testc=(TestControllerImpl) appcon.getBean("testController");

testc.save();

}

}

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:汽车电路故障检修的2个经典案例
下一篇:35 字典中 format_map方法格式化字符串序列与迭代 clear copy deepcopy
相关文章

 发表评论

暂时没有评论,来抢沙发吧~