通常,应用程序开发者不需要子类化ApplicationContext实现类。相反,可以通过插入特殊集成接口的实现来扩展SpringIoC容器。接下来的几节描述了这些集成接口。使用BeanPostProcessor自定义BeanBeanPostProcessor接口定义了回调方法,您可以实现这些回调方法以提供您自己的(或覆盖容器的默认值)实例化逻辑、依赖关系解析逻辑等。如果您想在Spring容器完成实例化、配置和初始化bean后实现一些自定义逻辑,您可以插入一个或多个自定义BeanPostProcessor实现。你可以配置多个BeanPostProcessor实例,你可以通过设置order属性来控制这些BeanPostProcessor实例的运行顺序。仅当BeanPostProcessor实现了Ordered接口时,您才能设置此属性。如果您编写自己的BeanPostProcessor,您还应该考虑实现Ordered接口。有关详细信息,请参阅BeanPostProcessor和Ordered接口的javadoc。另请参阅有关BeanPostProcessor实例的编程注册的说明。BeanPostProcessor实例对Bean实例进行操作。也就是说,SpringIoC容器实例化一个Bean实例,然后BeanPostProcessor实例工作。BeanPostProcessor实例按容器划分范围。这仅在您使用容器层次结构时才有意义。如果您在容器中定义BeanPostProcessor,它只会对容器中的beans进行后处理。换句话说,一个容器中定义的Bean不会被另一个容器中定义的BeanPostProcessor进行后处理,即使这两个容器属于同一层次结构。ApplicationContext将自动检测实现配置元数据中定义的BeanPostProcessor接口的Bean。ApplicationContext将这些bean注册为后处理器,以便稍后在创建bean时调用它们。Bean后处理器可以像其他bean一样部署在容器中。请注意,在配置类上使用@Bean工厂方法声明BeanPostProcessor时,工厂方法的返回类型应该是实现类本身或至少是org.springframework.beans.factory.config.BeanPostProcessor接口,显式指定bean的后处理器属性。否则,ApplicationContext在完全创建之前无法按类型自动检测它。这种早期类型检测至关重要,因为BeanPostProcessor需要尽早实例化,以便用于初始化上下文中的其他bean。下面的示例展示了如何在ApplicationContext的上下文中编写、注册和使用BeanPostProcessors。公共类HelloWorld{私有字符串消息;publicvoidsetMessage(Stringmessage){this.message=message;}publicvoidgetMessage(){System.out.println("你的信息:"+message);}publicvoidinit(){System.out.println("Bean正在初始化。");}publicvoiddestroy(){System.out.println("Bean将立即销毁。");”BeforeInitialization:"+beanName);返回豆;//你也可以返回任何其他对象}publicObjectpostProcessAfterInitialization(Objectbean,StringbeanName)throwsBeansException{System.out.println("AfterInitialization:"+bean姓名);返回豆;//你也可以返回任何其他对象}}以下是MainApp.java文件的内容这里你需要注册一个关闭钩子registerShutdownHook()方法,它是在AbstractApplicationContext类上声明的。这将确保正常关闭并调用关联的销毁方法。导入org.springframework.context.support.AbstractApplicationContext;导入org.springframework.context.support.ClassPathXmlApplicationContext;publicclassMainApp{publicstaticvoidmain(String[]args){AbstractApplicationContextcontext=newClassPathXmlApplicationContext("Beans.xml");HelloWorldobj=(HelloWorld)context.getBean("helloWorld");obj.getMessage();context.registerShutdownHook();}}<豆类ss="com.tutorialspoint.InitHelloWorld"/>Output:BeforeInitialization:helloWorldBeanisgoingthroughinit.AfterInitialization:helloWorldYourMessage:HelloWorld!Bean现在将销毁。BeanFactoryPostProcessor实现用于读取配置元数据,并修改它在IOC容器实例化Bean之前。我们可以配置多个BeanFactoryPostProcessor,也可以通过设置order属性来控制这些BeanFactoryPostProcessor的执行顺序。仅当BeanFactoryPostProcessor实现了Ordered接口时,您才能设置order属性。BeanFactoryPostProcessor是一个函数式接口,它有一个抽象方法postProcessBeanFactory(),实现这个方法,可以自定义和修改Bean的定义。请注意,调用此方法时,已加载所有bean定义,但尚未实例化任何bean。它允许覆盖或添加属性,即使对于急切初始化的bean也是如此。BeanFactoryPostProcessor定义如下:@FunctionalInterface@FunctionalInterfacepublicinterfaceBeanFactoryPostProcessor{voidpostProcessBeanFactory(ConfigurableListableBeanFactorybeanFactory)throwsBeansException;}BeanFactoryPostProcessor例子举个简单的例子,如果我们在运行时在属性配置文件中为数据库配置设置了属性,更改url,其他属性不变。我们可以使用BeanFactoryPostProcessor访问bean定义并修改属性值。当然,我们也可以配置多个properties文件并进行切换,这里只是举个例子。db.propertiesdb.driverClassName=com.mysql.jdbc.Driverdb.url=jdbc:mysql://localhost:3306/netjsdb.username=rootdb.password=adminpool.initialSize=5datasource定义BeanFactoryPostProcessor实现类importorg.springframework.beans.BeansException;importorg.springframework.beans.MutablePropertyValues;importorg.springframework.beans.PropertyValue;importorg.springframework.beans.factory.config。BeanDefinition;导入org.springframework.beans.factory.config.BeanFactoryPostProcessor;导入org.springframework.beans.factory.config.ConfigurableListableBeanFactory;导入org.springframework.core.Ordered;公共类TestDBPostProcessor实现BeanFactoryPostProcessor,Ordered//获取数据源beanBeanDefinitionbd=beanFactory.getBeanDefinition("dataSource");如果(bd.hasPropertyValues()){MutablePropertyValuespvs=bd.getPropertyValues();PropertyValue[]pvArray=pvs.getPropertyValues();for(PropertyValuepv:pvArray){System.out.println("pv--"+pv.getName());//改变url属性的值if(pv.getName().equals("url")){pvs.add(pv.getName(),"jdbc:mysql://localhost:3306/TestSchema");}}}}@OverridepublicintgetOrder(){//TODO自动生成的方法存根return0;}}在配置文件中注册BeanFactoryPostProcessorpublicListfindAllEmployees(){System.out.println("URL"+((BasicDataSource)jdbcTemplate.getDataSource()).getUrl());返回this.jdbcTemplate.query(SELECT_ALL_QUERY,(ResultSetrs)->{Listlist=newArrayList();while(rs.next()){Employeeemp=newEmployee();emp.setEmpId(rs.getInt("id"));emp.setEmpName(rs.getString("name"));emp.setAge(rs.getInt("age"));list.add(emp);}returnlist;});}publicclassApp{publicstaticvoidmain(String[]args){ClassPathXmlApplicationContextcontext=newClassPathXmlApplicationContext("appcontext.xml");EmployeeDAOdao=(EmployeeDAO)context.getBean("employeeDAOImpl");ListempList=dao.findAllEmployees();for(员工emp:empList){System.out.println("姓名-"+emp.getEmpName()+"年龄-"+emp.getAge());}context.close();}}Output:在postProcessBeanFactorypv--driverClassNamepv--urlpv--usernamepv--passwordpv--initialSizeURLjdbc:mysql://localhost:3306/TestSchemaFactoryBean在Spring的bean容器中,有两种bean:普通bean和工厂beanSpringdirect使用前者,后者可以自己生成对象,由框架管理。简单的说,我们可以通过实现org.springframework.beans.factory.FactoryBean接口来创建工厂bean。FactoryBean接口提供三个方法:TgetObject():返回工厂创建的对象的实例。实例可能会被共享,这取决于工厂返回的是单例还是原型bean。booleanisSingleton():如果此FactoryBean返回单例,则返回true,否则返回false。此方法的默认实现返回true。类getObjectType():返回getObject()方法返回的对象类型,如果事先不知道类型,则返回null。示例:publicclassTool{privateintid;//标准构造函数、getter和setter}publicclassToolFactoryimplementsFactoryBean{privateintfactoryId;私有inttoolId;@OverridepublicToolgetObject()throwsException{returnnewTool(toolId);}@OverridepublicClass>getObjectType(){returnTool.class;}@OverridepublicbooleanisSingleton(){返回false;}//标准设置器和获取器}@ConfigurationpublicclassFactoryBeanAppConfig{@Bean(name="tool")publicToolFactorytoolFactory(){ToolFactoryfactory=newToolFactory();factory.setFactoryId(7070);factory.setToolId(2);返厂;}}publicclassApplication{publicstaticvoidmain(String[]args){AnnotationConfigApplicationContextcontext=newAnnotationConfigApplicationContext(FactoryBeanAppConfig.class);工具tool=续ext.getBean("工具",工具类);System.out.println(工具);ToolFactorytoolFactory=context.getBean("&tool",ToolFactory.class);System.out.println(工具工厂);context.close();}}当我们要获取一个FactoryBean实例时,需要在beanid前面加上&符号,比如getBean('&tool')