欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > spring214

spring214

2025/11/20 5:47:51 来源:https://blog.csdn.net/qq_36022463/article/details/145624998  浏览:    关键词:spring214
spring父子容器:

为什么会有spring父子容器,,因为一般大一点的项目都是分模块的,,不同的人开发不同的模块,,可以在两个不同的模块中,,使用相同的beanName,,如果不是父子容器,,那么spring的配置文件,后面的会覆盖前面的,,有一个bean就会找不到,,,
要么写成兄弟容器,,两个并列的容器,,通过ctx.setParent()设置一个相同的父容器,,但是,这样不能从其中一个容器,获取到另一个容器的bean,两个容器是相互独立的,,,

所以需要父子容器,,在子容器中,可以获取父容器的Bean,在父容器中不能获取子容器的bean,,,就跟springmvc中一样,

   public static void main(String[] args) {// 父子容器ClassPathXmlApplicationContext parent = new ClassPathXmlApplicationContext("merchant_beans.xml");// springmvc中  service中不能注入controller ,,===》 父子容器ClassPathXmlApplicationContext child = new ClassPathXmlApplicationContext("consumer_beans.xml");child.setParent(parent);// 重新初始化容器child.refresh();RoleService consumerBean = child.getBean(RoleService.class);merchant.RoleService merchantService = child.getBean(merchant.RoleService.class);}
scope作用域
  • singleton : 单例==》 容器启动会直接初始化
  • prototype: 多例 ==〉 懒加载,,使用到的时候才会初始化
  • request
  • session
  • application
  • websocket
@Bean
@Scope(scopeName = "prototype")User user(){return new User();}
工厂bean

spring整合第三方框架:

  • 静态工厂
public class OkHttpClientStaticFactory {public static OkHttpClient getInstance(){OkHttpClient.Builder builder = new OkHttpClient.Builder();builder.setReadTimeout$okhttp(5000);return builder.build();}}
    <bean class="com.cj.demo214.OkHttpClientStaticFactory" factory-method="getInstance" id="okHttpClient"/>
  • 实例工厂
public class OkHttpClientStaticFactory {private static OkHttpClient okHttpClient;static {OkHttpClient.Builder builder = new OkHttpClient.Builder();builder.setReadTimeout$okhttp(5000);okHttpClient = builder.build();}public static OkHttpClient getInstance(){return okHttpClient;}}
  <bean class="com.cj.demo214.OkHttpClientFactory" id="clientFactory"/><bean factory-bean="clientFactory" factory-method="getOkHttpClient" id="okHttpClient2"/>
  • FacotryBean : 用的最广泛的,,注入第三方bean
public class OkHttpClientFactoryBean implements FactoryBean<OkHttpClient> {/*** 返回真正的 bean对象* @return* @throws Exception*/@Overridepublic OkHttpClient getObject() throws Exception {OkHttpClient.Builder builder = new OkHttpClient.Builder();return builder.build();}/*** 返回对象的类型* @return*/@Overridepublic Class<?> getObjectType() {return OkHttpClient.class;}/*** 返回false : 只是不是singleton,,, 但不一定是prototype* @return*/@Overridepublic boolean isSingleton() {// 调父类的方法,默认就是truereturn FactoryBean.super.isSingleton();}
}
<!--    这里向spring注册的是,,这个factoryBean中getObject返回的值--><bean class="com.cj.demo214.OkHttpClientFactoryBean" id="client3"/>
 public static void main(String[] args) {ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");Object client3 = ctx.getBean("client3");// 获取factoryBean,,前面加上&Object factoryBean = ctx.getBean("&client3");System.out.println("client3.getClass() = " + client3.getClass());System.out.println("factoryBean = " + factoryBean);}

FactoryBean默认是懒加载的,,,,

spring加载配置文件
<!--     将配置文件中的key-value,,, 注册到spring容器中-->
<context:property-placeholder location="classpath:db.properties"/>

或者使用 @PropertySource("classpath:db.properties")

后置处理器
  • BeanPostProcessor : bean的后置处理器,,所有的bean都会执行这个
  • BeanFactoryPostProcessor

bean初始化执行的方法:

  • 执行设置的 init-method ,,
  • 如果实现了InitializingBean 会执行afterPropertiesSet方法

bean的加载过程:
xml内容 ===〉 BeanDefinition ⇒ 根据beanDefinition的信息实例化bean ===》 给bean的属性赋值(@Autowired @Value等注解注入的值) ===> 调用bean的各种初始化方法 ===》 成品的bean

有两个地方可以对bean修改:
BeanFactoryPostProcessor : bean工厂的后置处理器,,这里会对beanDefinition进行修改,最终影响到生成的bean,,比如说${xxx}占位符,,就是在。BeanFactoryPostProcessor中拦截下来,获取BeanDefinition然后通过visitor ,遍历BeanDefinition并修改其中的属性值。。

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {/*** 只会执行一次,,,, 这个相当于spring容器,,只会执行一次后置处理* 这个时候 BeanDefinition 已经有了,,但是bean还没有生成* @param beanFactory  这个参数相当于 spring容器* @throws BeansException*/@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
//        beanFactory.getBeanDefinition("")// 获取spring容器中,所有的beanNameString[] beanDefinitionNames = beanFactory.getBeanDefinitionNames();System.out.println(Arrays.toString(beanDefinitionNames));// bean的提前初始化,,,按理说此时bean是没有生成的,,, 这个比spring容器初始化更早
//        User user = beanFactory.getBean(User.class);
//        System.out.println("user = " + user);BeanDefinition userBeanDefinition = beanFactory.getBeanDefinition("user");//是一个专门用来访问BeanDefinition中属性的工具==》 直接操作 BeanDefinition 比较麻烦,spring中提供了这样一个访问器//BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(strVal -> {// 访问BeanDefinition中所有的值if (strVal.equals("zs")) {return "cc";}return strVal;});// 像 ${xxx} 占位符,,, 就是这样根据 visitor访问 BeanDefinition中的值,,如果发现是 占位符${xxx},, 就将这些占位符替换成spring容器中读取出来的值// 修改userBeanDefinition中的值visitor.visitBeanDefinition(userBeanDefinition);System.out.println("postProcessBeanFactory");}
}

BeanPostProcessor: bean的后置处理器,他起作用的时候,bean已经生成了,,此时就可以对已经生成的bean对象做一些修改,把已经生成的bean拦截下来,做一些修改

public class UserBeanPostProcessor implements BeanPostProcessor {/*** 所有的bean都会执行一边* 初始化之前* @param bean  对象本身* @param beanName 对象的名字* @return* @throws BeansException*/@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("post process initalization ");if (beanName.equals("user")){User user = (User) bean;user.setUsername("waterkid");return user;}return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);}/*** 初始化之后* @param bean* @param beanName* @return* @throws BeansException*/@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("postProcessAfterInitialization");return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词