你们都知道,项目启动的时候,spring读取xml文件,将配置的bean 或者 注解下的controller service dao所有实例化。而后注入到代码里去使用。那么咱们怎么本身去获取某个实例化的bean呢。本身new是没用的。java
举个场景,redis
假设我写了一个类spring
public class A{ @Resource private static ADao aDao; static{ aDao.select(); } public static void getA(){ ... } }
当 别的类里调用A.getA()的时候,调用的是静态方法,A并不会实例化,只是初始化,也就是说aDao-null;数据库
可能会以为我设定这个A类很奇葩,可是有的场景就是这样,为了提升性能,我只容许查库一次,之后读取内存。(不放到redis为了安全),因此就要用只会第一次初始化才会被执行的静态代码块。编程
这个时候我就须要本身去获取aDao了。安全
那么怎么获取呢?mybatis
首先咱们要知道几个问题app
1, aDao已经实例化了,只是在spring容器中,还不知道怎么去取。ide
2,若是用的mybatis的接口式编程,那么aDao只是一个接口,他的实现类是MapperFactoryBean,并非自己,性能
<bean id="aDap" class=" .../.../aDao"/>这种写法是错误的。
3, ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");
context.getBean("BeanName");
这种作法是日常测试的时候,在不启动spring的时候的一种加载配置文件实例化bean的方法。
在一个正常启动的项目中,这样作是不对的,会使spring从新实例化,从新创建数据库链接池。这至关于重启一个正在运行的项目,是很严重的。
因此咱们要用spring给咱们提供的接口去搞。
方法一:实现BeanFactoryAware接口
代码以下:
@Service public class BeanUtils implements BeanFactoryAware { // Spring的bean工厂 private static BeanFactory beanFactory; @Override public void setBeanFactory(BeanFactory factory) throws BeansException { beanFactory=factory; } public static<T> T getBean(String beanName){ return (T) beanFactory.getBean(beanName); } }
这个类的意思大致这么几个
1,实现BeanFactoryAware接口,这个接口可让咱们在项目启动后获取bena工厂的实例,从而为所欲为的获取咱们想要的bean实例。
2,setBeanFactory()方法是用的spring的依赖注入,set方法是三种注入方式之一。这样实例才会注入到该类里。
既然要注入,那么咱们必须设置BeanUtils这个类也要在项目启动的时候被spring实例化,我这里是采用注解的方式@service来实现。
3,静态getBean方法,这里方法必须是静态的,由于你若是本身去new这个BeanUtils类的话,beanFactory是不会被注入进去的。
方法二,很是简单的一种用法。
ContextLoaderListener.getCurrentWebApplicationContext().getBean ("beanName");
使用 上下文监听器去获取上下文,而后获取bean,这个方法细心的同窗应该能看到,这是上面我讲的一种错误用法的改变。3, ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");,用一句话概述就是,new是无论用的,从容器中拿出来才是正道。
关于ContextLoaderListener这个监听器就很少说了。
这里只列出两种,还有几种方式,也能够获取。
若是哪里解释的不对,但愿大神指点下小弟,毕竟本身摸索,不免会出错。