Spring神经元(第六根)

96 阅读2分钟

Bean的生命周期

管理Bean的生命行为有2个时机:

  • Bean的全部依赖关系被注入后(初始化)。 初始化该Bean所需的各种资源。
    • 使用ini t-method或default-ini t-method属性配置
    • 实现Ini tial izingBean接口,所实现的该接口中afterPropertiesSet ()方法就是生命周期方法
  • Bean即将销毁之前。 回收该Bean曾使用的各种资源。
    • 使用destroy method属性或defaul t-destroy; method属性配置.
    • 实现Di sposableBean接口;所实现的该接口中destroy()方法就是生命周期方法
<bean id="testBean" class="com.example.ssm.day5.wp.TestBean" init-method="init"  
destroy-method="close"/>
//2个method是2中生命周期方法,

image.png

作用域不同步的问题

当singleton作用域Bean依赖prototyee作用域Bean时,singleton作用域Bean只有一 次初始化的机会, 它的依赖关系也只在初始化阶段被设置 而它所依赖的prototype作用域Bean则会不断地产生新的Bean实例,这将导致singleton作用域的Bean的依赖得不到即时更新: singleton作用域Bean所依赖的将一直是最开始的prototype Bean, 每次通过singleton Bean来获取它所依赖的prototype作用域的Bean时,系统总返回最开始那个prototype Bean

  • 这就违背了我们设置prototype的初衷。 柯时将一个Bean设为prototype? 为什么要将Bean设为prototype?

何时把Bean设置位prototype

不要把prototype注入进singleton Bean,会导致prototpye 转换位singleton

<!--.置为prototype,希望程序每次使用dog时,都是全新的实例-->  
<bean id="dog" class="com.example.ssm.day6.NewDog"  
p:name="你好" scope="prototype"/>  
<!--依赖注入的dog但实是一个singleton-->  
<bean id="person" class="com.example.ssm.day6.Person"  
p:dg-ref="dog"/>

解决 1.放弃依赖注入 在person里面接ApplicationContext接口,同时生成ApplicationContext的set方法,同时在person类种生成getDog方法,return (Dog)ctx.getBean("dog"),因为在get时,这个dog的bean是prototype。每次生成的都不一样 缺点:该Bean,必须和spring Api耦合,造成代码污染 2.lookup注入 把Person定义位抽象类,同时里面的getDog页定义位抽象方法 了解动态代理技术

<bean id="person" class="com.example.ssm.day6.Person">  
    <lookup-method name="getDog"></lookup-method>  
</bean>

抽象方法

public abstract class Person
{
//通过该getDog方法来每 次获取全新的实例
	public abstract DOg getDog() ;
}

这段xml配置就等于

public class Person implements ApplicationContext {  
    private ApplicationContext ctx;  
  
    public Dog getDog() {  
        return (Dog) ctx.getBean("person");  
    }
}

调用getter方法

使用PropertyPathF actoryBean即可,肯定需要指定两个东西:

  • 调用哪个对象:.setTargetObject (0bjecttarget0bject)指定调用哪个对象。 setTargetBeanName (String beanName): 只要指定容器bean的d即可。
  • 调用哪个getter方法: setProper tyPath(String propertyPath)指定调用哪个getter方法 此处支持属性路径的写法: user.name: ->指定对象.getUser(). getName -> 指定对象. getAbc(). getXyz(). getDef(). getWawa();
<bean id="dog" class="com.example.ssm.day7.Dog"  
    c:_0="八嘎" c:_1="2"/>  
<bean id="person" class="com.example.ssm.day7.Person"  
c:_0="你好" c:_1="12"/>  
<bean id="theAge" class="org.springframework.beans.factory.config.PropertiesFactoryBean"  
      p:targetBeanName="person"  
      p:propertyPath="dog.age"/>  
/>

调用Person容器里面的Dog的年龄的get方法