怎么根据spring的beanName获取bean的作用域scope

怎么根据spring的beanName获取bean的作用域scope,第1张

定义Bean

Bean名称由BeanNameGenerator生成(@Component,@Controller,@Service,@Repository都有个name属性用于显示的指定Bean Name;默认是类名首字母小写)

也可使用<context:component-scan/>中的name-generator自定义Bean的命名策略,但是要实现BeanNameGenerator接口并且包含一个无参构造器

作用域

@Scope注解标识Bean的作用域。默认是singleton。

实例

1项目结构

2pomxml

+ View Code

3spring-beanannotationxml

+ View Code

4BeanAnnotationjava

+ View Code

5TestBasejava

+ View Code

6TestBeanAnnotationjava

+ View Code

7效果预览

如何取得Spring管理的bean (请用第3种方法):

1、servlet方式加载时,

webxml

Xml代码

<servlet>

<servlet-name>springMVC</servlet-name>

<servlet-class>orgspringframeworkwebservletDispatcherServlet</servlet-class>

<init-param>

<param-name>contExtConfigLocation</param-name>

<param-value>classpath:/springMVCxml</param-value>

</init-param>

<load-on-startup>1</load-on-startup>

</servlet>

spring容器放在ServletContext中的key是orgspringframeworkwebservletFrameworkServletCONTEXTspringMVC

注意后面的springMVC,是你的servlet-name配置的值,注意适时修改。

Java代码

ServletContext sc=略

WebApplicationContext attr = (WebApplicationContext)scgetAttribute("orgspringframeworkwebservletFrameworkServletCONTEXTspringMVC");

2、listener方式加载时:

webxml

Xml代码

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/applicationContext</param-value>

</context-param>

<listener>

<listener-class>orgspringframeworkwebcontextContextLoaderListener</listener-class>

</listener>

jsp/servlet可以这样取得

Java代码

ServletContext context = getServletContext();

WebApplicationContext applicationContext = WebApplicationContextUtils getWebApplicationContext(context);

3、通用的方法来了,神器啊,前的 1、2两种方法并不通用,可以抛弃了。

在配置文件中加入:

Xml代码

<!-- 用于持有ApplicationContext,可以使用SpringContextHoldergetBean('xxxx')的静态方法得到spring bean对象 -->

<bean class="comxxxxxSpringContextHolder" lazy-init="false" />

Java代码

import orgspringframeworkcontextApplicationContext;

import orgspringframeworkcontextApplicationContextAware;

/

以静态变量保存Spring ApplicationContext, 可在任何代码任何地方任何时候中取出ApplicaitonContext

/

public class SpringContextHolder implements ApplicationContextAware {

private static ApplicationContext applicationContext;

/

实现ApplicationContextAware接口的context注入函数, 将其存入静态变量

/

public void setApplicationContext(ApplicationContext applicationContext) {

SpringContextHolderapplicationContext = applicationContext; // NOSONAR

}

/

取得存储在静态变量中的ApplicationContext

/

public static ApplicationContext getApplicationContext() {

checkApplicationContext();

return applicationContext;

}

/

从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型

/

@SuppressWarnings("unchecked")

public static <T> T getBean(String name) {

checkApplicationContext();

return (T) applicationContextgetBean(name);

}

/

从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型

/

@SuppressWarnings("unchecked")

public static <T> T getBean(Class<T> clazz) {

checkApplicationContext();

return (T) applicationContextgetBeansOfType(clazz);

}

/

清除applicationContext静态变量

/

public static void cleanApplicationContext() {

applicationContext = null;

}

private static void checkApplicationContext() {

if (applicationContext == null) {

throw new IllegalStateException("applicaitonContext未注入,请在applicationContextxml中定义SpringContextHolder");

}

}

}

spring的bean命名空间中,除了spring内部的bean,还有 自己定义的bean 。有时候,我们需要确定自己定义的bean 哪些生效 了。

使用spring的 applicationContextgetBeanDefinitionNames() ,来获取命名空间内所有的bean的name,然后根据bean的name获取 bean的class信息 ,根据 需要的bean的包路径 ,来 过滤 出自己需要的bean的信息。

需要的bean的信息,主要包括:bean的类路径,和bean的name。

其中同一个bean的类型下,有可能有多个name。如下:

定义如下工具类,可以在 非spring命名空间内 用来获取spring命名空间:

如 在spring命名空间内 ,通过如下方式 注入ApplicationContext 即可:

输出内容如下:

如果想 获取某个类,有哪些bean的实例 ,可以通过如下方法:

返回的结果,为此java类对应的bean的name,如下:

如果,java类不存在对应的bean的实例,则返回空的字符串数组

配置了parent属性的bean可以继承指定的bean的属性。

例子:

Singerjava

contextxml,定义的Jane和Bibi都指定ChineseFemaleSinger为parent,她们将继承ChineseFemaleSinger的country和gender属性。

Appjava

执行App的main方法,输出:

配置了depends-on的bean会在被指定的bean初始化之后初始化,销毁前销毁。

例子:

BeanAjava

BeanBjava

contextxml

beanA和beanB都配置了init-method和destroy-method,在初始化和销毁时输出一些信息,以便判断初始化和销毁的顺序。

Appjava

执行main方法,输出

可以看到,beanB在beanA初始化后初始化,在beanA销毁前销毁。

factory-bean属性指定一个bean,factory-method指定某个返回一个对象的方法。

例子:

Phonejava

IphoneFactoryjava

contextxml

Appjava

执行main方法,输出

根据注释proxyBeanMethods是为了让使用@Bean注解的方法被代理而实现bean的生命周期的行为。

1设置为true,那么直接调用方法获取bean,不会创建新的bean,而是会走bean的生命周期的行为。

2设置为false, 那么直接调用方法获取bean,会创建新的bean,且不会走bean的生命周期的行为。

MyBean construct打印了两次,说明被new了两次

MyBean construct只打印了一次,说明只被new了一次。

1 在Spring Boot可以扫描的包下

假设我们编写的工具类为SpringUtil。

如果我们编写的SpringUtil在Spring Boot可以扫描的包下或者使用@ComponentScan引入自定义的包了,那么原理很简单,只需要使得SpringUtil实现接口:ApplicationContextAware,然后加上@Component 注解即可,具体编码如下:

comkfitbaseutilSpringUtil:

package comkfitbaseutil;

import orgspringframeworkbeansBeansException;

import orgspringframeworkcontextApplicationContext;

import orgspringframeworkcontextApplicationContextAware;

import orgspringframeworkstereotypeComponent;

/

普通类调用Spring bean对象:

说明:

1、此类需要放到Appjava同包或者子包下才能被扫描,否则失效。

@author Administrator

/

@Component

publicclass SpringUtil implements ApplicationContextAware{

privatestatic ApplicationContext applicationContext = null;

@Override

publicvoid setApplicationContext(ApplicationContext applicationContext) throwsBeansException {

if(SpringUtilapplicationContext == null){

SpringUtilapplicationContext = applicationContext;

}

Systemoutprintln("---------------------------------------------------------------------");

Systemoutprintln("---------------------------------------------------------------------");

Systemoutprintln("---------------comkfitbaseutilSpringUtil------------------------------------------------------");

Systemoutprintln("========ApplicationContext配置成功,在普通类可以通过调用SpringUtilsgetAppContext()获取applicationContext对象,applicationContext="+SpringUtilapplicationContext+"========");

Systemoutprintln("---------------------------------------------------------------------");

}

//获取applicationContext

publicstatic ApplicationContext getApplicationContext() {

returnapplicationContext;

}

//通过name获取 Bean

publicstatic Object getBean(String name){

return getApplicationContext()getBean(name);

}

//通过class获取Bean

publicstatic <T> T getBean(Class<T> clazz){

return getApplicationContext()getBean(clazz);

}

//通过name,以及Clazz返回指定的Bean

publicstatic <T> T getBean(String name,Class<T> clazz){

return getApplicationContext()getBean(name, clazz);

}

}

启动应用,查看控制台的打印信息是否有:

======ApplicationContext配置成功,在普通类可以通过调用SpringUtilsgetAppContext()获取applicationContext对象,

2 不在Spring Boot的扫描包下方式一

这种情况处理起来也很简单,先编写SpringUtil类,同样需要实现接口:ApplicationContextAware,具体编码如下:

simplepluginspringSpringUtil

package simplepluginspring;

import orgspringframeworkbeansBeansException;

import orgspringframeworkcontextApplicationContext;

import orgspringframeworkcontextApplicationContextAware;

publicclass SpringUtil implements ApplicationContextAware{

privatestatic ApplicationContext applicationContext = null;

@Override

publicvoid setApplicationContext(ApplicationContext applicationContext) throwsBeansException {

if(SpringUtilapplicationContext == null){

SpringUtilapplicationContext = applicationContext;

}

Systemoutprintln("---------------------------------------------------------------------");

Systemoutprintln("---------------------------------------------------------------------");

Systemoutprintln("---------------simplepluginspringSpringUtil------------------------------------------------------");

Systemoutprintln("========ApplicationContext配置成功,在普通类可以通过调用SpringUtilsgetAppContext()获取applicationContext对象,applicationContext="+SpringUtilapplicationContext+"========");

Systemoutprintln("---------------------------------------------------------------------");

}

//获取applicationContext

publicstatic ApplicationContext getApplicationContext() {

returnapplicationContext;

}

//通过name获取 Bean

publicstatic Object getBean(String name){

return getApplicationContext()getBean(name);

}

//通过class获取Bean

publicstatic <T> T getBean(Class<T> clazz){

return getApplicationContext()getBean(clazz);

}

//通过name,以及Clazz返回指定的Bean

publicstatic <T> T getBean(String name,Class<T> clazz){

return getApplicationContext()getBean(name, clazz);

}

}

之后这一步才是关键,使用@Bean注解,在Appjava类中将SpringUtil注解进来,代码如下:

package comkfit;

import orgspringframeworkbootSpringApplication;

import orgspringframeworkbootautoconfigureSpringBootApplication;

import orgspringframeworkbootwebservletServletComponentScan;

import orgspringframeworkcontextannotationBean;

import orgspringframeworkcontextannotationImport;

import simplepluginspringSpringUtil;

/

Hello world!

/

//其中@SpringBootApplication申明让spring boot自动给程序进行必要的配置,等价于以默认属性使用@Configuration,@EnableAutoConfiguration和@ComponentScan

@SpringBootApplication

@ServletComponentScan

public class App {

/注册Spring Util

这里为了和上一个冲突,所以方面名为:springUtil2

实际中使用springUtil

/

@Bean

public SpringUtil springUtil2(){return new SpringUtil();}

/

参数里VM参数设置为:

-javaagent:\lib\springloaded-124RELEASEjar -noverify

@param args

/

public static void main(String[] args) {

SpringApplicationrun(Appclass, args);

}

}

3 不在Spring Boot的扫描包下方式二

代码基本和上面都是相同的,主要是在Appjava中使用@Import进行导入。

而且在SpringUtil是不需要添加@Component注解

@SpringBootApplication

@ServletComponentScan

@Import(value={SpringUtilclass})

publicclass App {

//省略其它代码

}

说明以上3中方式都生效了,这3中方式根据实际情况选择一种方式就可以了。

那么这样子在普通类既可以使用:

SpringUtilgetBean() 获取到Spring IOC容器中的bean。

当然也可以在Spring管理的类中使用:

@Resouce或者@Autowired 进行注入使用,当然我们这个类的核心是普通类可以调用spring的bean进行使用了,是不是很神奇呢。

<bean id="springBean" scope="prototype" class=""<property name="name" value="chen"/</bean<bean id="myAction" scope="prototype" class=""<property name="springBean" ref="springBean"/</bean如果是j2ee应用,启动web应用时将会自动加载ApplicationContext实例(Spring容器负责创建Bean实例)一旦struts2的myAction实例化,其中的SpringBean也会被自动注入进来,从而达到使用SpringBean的目的。[问题]但是仍有需要通过代码来调用SpringBean的情况:1)对于不是由spring创建管理的类,如在java 代码中直接使用new去创建一个对象,并且想在这个对象中使用SpringBean;因为这个对象并不是由Spring容器创建管理的类,所以即使它有setter方法,容器的springBean也不会被注入。2)动态更改springBean中的属性值,如在代码运行时,name值需要发生变动;3)对于一个独立的应用程序[解决]定义一个非Spring容器创建管理的类public class NonSpringClass implements ServletContextAware {private SpringBean springBean;//如果 testGetBean不是被Spring容器创建管理,即使它有setter方法,容器的springBean也不会被注入。public void setSpringBean(SpringBean springBean){thisspringBean=springBean;}//利用ApplicationContext 从spring容器中获得springBean;//Spring有两个核心接口BeanFactory和ApplicationContext,其中ApplicationContext是BeanFactory的子接口,//它们代表了Spring容器,Spring容器是产生Bean的工厂,用于管理容器中的Bean。

ModelAndView mav=new ModelAndView()

mavaddObject("bean",你的bean);

页面返回的各个属性值${beanxxx}

以上就是关于怎么根据spring的beanName获取bean的作用域scope全部的内容,包括:怎么根据spring的beanName获取bean的作用域scope、如何取得Spring管理的bean、spring查看自定义的bean等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/10152986.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-05
下一篇2023-05-05

发表评论

登录后才能评论

评论列表(0条)

    保存