spring 疑问

现在用的是SSI框架,但在开发中遇到一些疑惑,希望高手给予解答。
因为是ssi的框架,项目在web.xml中定义了监听器,用于项目启动的时候就加载所有的bean

[code="xml"]

contextConfigLocation
classpath*:/config/spring/applicationContext.xml

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

[code="xml"]

但项目中有些类中,需要注入,一时想不出来好方法,就用了读取配置文件的方法,如下
ApplicationContext ctx = ClassPathXmlApplicationContext("配置文件");
但在配置定时器的时候发生了产生两个实例的问题;

我想问一下,
第一个问题:每次像ApplicationContext ctx = ClassPathXmlApplicationContext("配置文件");调用就重新实例话所有的bean,还是再次产生多个bean,造成多了一倍;这样做是不是会造成实例越来越多?
第二个问题,怎么查看项目启动后所有的已经实例化的bean?

0

10个回答

什么叫“但项目中有些类中,需要注入”,什么意思?spring本身就可以用配置文件或者注解进行类的注入的啊。

为什么配置定时任务要启动两个IoC容器?直接把已经启动的IoC容器中的Bean取出来用不行么?

每次做ApplicationContext ctx = ClassPathXmlApplicationContext("配置文件");
这个操作,所有bean都要重新初始化一次,如果多次执行但是不销毁容器,那就只能等内存溢出了。

不明白你的问题,能否直接说你想实现什么功能?

0

要不就把用到的类也在xml中配置好当做bean来管理吧。

0

来学习。
你这样重新实例化了一个context,当你调用她里面的bean A对象时,才会实例化那bean A对象,而且在她所在的context里面只实例化一次,就相当于你new 出一个新对象放在堆里面一样,当你再次在引用这个context里的这个bean时,就相当于你的新句柄再次指向原来那个堆里的对象,而不是重新创建一个堆存储块。

还有你说的某些类需要注入,好像也没必要这样来重新再定义一个context吧

0

:oops: 如果你知道原理了也给我说下,我上次也在我的程序里实例化了一个
ApplicationContext ctx = ClassPathXmlApplicationContext("配置文件");
然后启动tomcat之后就飙出很多东西来,好像和我在web.xml定义的contextConfigLocation冲突似的,然后我就改用beanFactory了

0

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的方式



org.springframework.web.context.ContextLoaderListener

网上的资料这么说的, :oops:

0

学习。
楼主既然有一些类需要注入,那么为什么不专门用一个类来做这件事,把需要注入的东西放到内存里(用hashMap封装好 id作为key),然后需要注入时,通过这个 bean的id 来从map中取得你需要的实体类实例化。

这样项目运行时,就只有两个地方存放所有的实例了,而且Map取东西也很快。

对于LZ提的问题,我也答不具体。只是提提参考意见。

0

对于部分需要手动注入,部分需要spring配置注入,解决方案想和大家一起讨论讨论:

小弟的是:

例如:
[code="java"]
class A extends AllFather{

public A (){
this.setServiceName('spring中bean的id')
}
}
[/code]

对于setServiceName(...)是在父类AllFather中的统一实现的

[code="java"]
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中
}

}

[/code]

估计其中对于什么时候调用父类的方法, 这个父类是静态或者其他的等等需要继续改完善。讨论讨论。

0

你的配置没有问题啊,大家都是这样用的。注入的可以像下面这么做:
[code="java"]


public class ExampleBusinessObject {
// properties and collaborators
public void doIt() {
// do the actual work
}
}

[/code]

0

[quote]容器销毁? ApplicationContext怎么销毁?? [/quote]

在非Web应用中,手工加载Spring IoC容器,不能用ApplicationContext,要用AbstractApplicationContext。用完以后要记得调用ctx.close()关闭容器。如果不记得关闭容器,最典型的问题就是数据库连接不能释放。

代码如下:
[code="java"]
AbstractApplicationContext ctx= ClassPathXmlApplicationContext("配置文件");
//测试代码...
ctx.close();
[/code]

0

[code="java"]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");

}[/code]

自定义一个Listener,如上,在web.xml中加入

com.jax.listener.SystemInitListener

0
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!