
定义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等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)