问题描述
现在用的是SSI框架,但在开发中遇到一些疑惑,希望高手给予解答。因为是ssi的框架,项目在web.xml中定义了监听器,用于项目启动的时候就加载所有的bean<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:/config/spring/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>但项目中有些类中,需要注入,一时想不出来好方法,就用了读取配置文件的方法,如下ApplicationContext ctx = ClassPathXmlApplicationContext("配置文件");但在配置定时器的时候发生了产生两个实例的问题;我想问一下,第一个问题:每次像ApplicationContext ctx = ClassPathXmlApplicationContext("配置文件");调用就重新实例话所有的bean,还是再次产生多个bean,造成多了一倍;这样做是不是会造成实例越来越多?第二个问题,怎么查看项目启动后所有的已经实例化的bean? 问题补充:jjjssh 写道
解决方案
什么叫“但项目中有些类中,需要注入”,什么意思?spring本身就可以用配置文件或者注解进行类的注入的啊。为什么配置定时任务要启动两个IoC容器?直接把已经启动的IoC容器中的Bean取出来用不行么?每次做ApplicationContext ctx = ClassPathXmlApplicationContext("配置文件"); 这个操作,所有bean都要重新初始化一次,如果多次执行但是不销毁容器,那就只能等内存溢出了。不明白你的问题,能否直接说你想实现什么功能?
解决方案二:
public class SystemInitListener implements ServletContextListener, HttpSessionListener, HttpSessionAttributeListener {@SuppressWarnings("all") public void contextInitialized(ServletContextEvent sce) { WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext()); DefaultBiz defaultBiz = (DefaultBiz) wac.getBean("defaultBizImpl"); }自定义一个Listener,如上,在web.xml中加入 <listener> <listener-class>com.jax.listener.SystemInitListener</listener-class> </listener>
解决方案三:
引用容器销毁? ApplicationContext怎么销毁?? 在非Web应用中,手工加载Spring IoC容器,不能用ApplicationContext,要用AbstractApplicationContext。用完以后要记得调用ctx.close()关闭容器。如果不记得关闭容器,最典型的问题就是数据库连接不能释放。代码如下:AbstractApplicationContext ctx= ClassPathXmlApplicationContext("配置文件"); //测试代码...ctx.close();
解决方案四:
你的配置没有问题啊,大家都是这样用的。注入的可以像下面这么做:<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"><property name="targetObject" ref="exampleBusinessObject" /><property name="targetMethod" value="doIt" /></bean>public class ExampleBusinessObject {// properties and collaboratorspublic void doIt() {// do the actual work}}<bean id="exampleBusinessObject" class="examples.ExampleBusinessObject"/>
解决方案五:
对于部分需要手动注入,部分需要spring配置注入,解决方案想和大家一起讨论讨论:小弟的是:例如:class A extends AllFather{public A (){this.setServiceName('spring中bean的id')}}对于setServiceName(...)是在父类AllFather中的统一实现的class AllFather{public Service serviceName ;public Map map;public AllFather(){//调用map的填充方法}public void setServiceName(String id){this.serviceName =(Service)map.get(id)}private void setMap(String xmlsrpingfilurl){ //将bean都都封装到map中}}估计其中对于什么时候调用父类的方法, 这个父类是静态或者其他的等等需要继续改完善。讨论讨论。
解决方案六:
学习。楼主既然有一些类需要注入,那么为什么不专门用一个类来做这件事,把需要注入的东西放到内存里(用hashMap封装好 id作为key),然后需要注入时,通过这个 bean的id 来从map中取得你需要的实体类实例化。这样项目运行时,就只有两个地方存放所有的实例了,而且Map取东西也很快。对于LZ提的问题,我也答不具体。只是提提参考意见。
解决方案七:
web.xml 文件中一般包括 servlet, spring, filter, listenr的配置。加载顺序是 先加载filter 后加载spring,则filter中初始化操作中的bean为null;首先可以肯定 加载顺序与他们在web.xml 文件中的先后顺序无关。web.xml 中 listener 和 serverlet 的加载顺序为 先 listener 后serverlet最终得出结果:先 listener >> filter >> servlet >> spring 所以,如果过滤器中要使用到 bean,可以将spring 的加载 改成 Listener的方式<listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class></listener>网上的资料这么说的,
解决方案八:
如果你知道原理了也给我说下,我上次也在我的程序里实例化了一个ApplicationContext ctx = ClassPathXmlApplicationContext("配置文件"); 然后启动tomcat之后就飙出很多东西来,好像和我在web.xml定义的contextConfigLocation冲突似的,然后我就改用beanFactory了
解决方案九:
来学习。你这样重新实例化了一个context,当你调用她里面的bean A对象时,才会实例化那bean A对象,而且在她所在的context里面只实例化一次,就相当于你new 出一个新对象放在堆里面一样,当你再次在引用这个context里的这个bean时,就相当于你的新句柄再次指向原来那个堆里的对象,而不是重新创建一个堆存储块。还有你说的某些类需要注入,好像也没必要这样来重新再定义一个context吧
解决方案十:
要不就把用到的类也在xml中配置好当做bean来管理吧。