有哪些调查网站可以做兼职,哈尔滨免费网站制作,郑州二七区网站建设,石家庄网站建设策略概述
对于学习Spring的兄弟姐妹来说#xff0c;觉得这个问题很熟悉#xff0c;若是要把它回答得很清楚#xff0c;却是很为难#xff1f;平时写代码的时候#xff0c;不会在意这些概念问题#xff0c;但面试时这个问题出现的频率却是很高#xff0c;所以还是必须要掌握…概述
对于学习Spring的兄弟姐妹来说觉得这个问题很熟悉若是要把它回答得很清楚却是很为难平时写代码的时候不会在意这些概念问题但面试时这个问题出现的频率却是很高所以还是必须要掌握和理解。
Spring Bean定义有哪些方式
总的来说分三种 1基于xml的方式 2基于注解的方式 3基于java类的方式
1、基于xml的方式
XML配置的方式是Spring最早支持的方式不过现在XML方式已经用的比较少了基本上都是用后面的配置方式替代了。
示例
Data
ToString
public class Student {String name;int age;
}beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdbean idstudent classcom.koo.entity.Student/
/beanspublic class Client {public static void main(String[] args) {ClassPathXmlApplicationContext applicationContext new ClassPathXmlApplicationContext(classpath:spring-config.xml);System.out.println(applicationContext.getBean(student));}
}2、基于注解的方式
又分一下几种方式 1 使用Component注解 ComponentScan包扫描方式 2Configuration Bean方式 3FactoryBean方式 4Import方式 5Import ImportSelector方式 6Import ImportBeanDefinitionRegistrar方式 7BeanDefinitionRegistryPostProcessor方式 8BeanFactoryPostProcessor方式
1 使用Component注解 ComponentScan包扫描方式
为了解决bean太多时XML文件过大从而导致膨胀不好维护的问题。在Spring2.5中开始支持 Component、Repository、Service、Controller等注解定义bean。Component放在类名上面然后通过ComponentScan指定一个路径Spring进行扫描带有Componet注解的bean然后加至容器中。 Component
public class UserHandler {
}Service
public class UserService {
}Repository
public class UserDao {
}Controller
public class UserController {
}ComponentScan(com.koo.modules)
Configuration
public class AppConfig {
}/*** 通常情况下 ** Controller一般用在控制层* Service一般用在业务层* Repository一般用在持久层* Component一般用在公共组件上*/
public class Client {public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext new AnnotationConfigApplicationContext(AppConfig.class);System.out.println(applicationContext.getBean(userDao));System.out.println(applicationContext.getBean(userService));System.out.println(applicationContext.getBean(userController));System.out.println(applicationContext.getBean(userHandler));}
}2Configuration Bean方式
这种方式其实也是我们最常用的方式之一Configuration用来声明一个配置类然后使用 Bean 注解声明一个bean将其加入到Spring容器中。通常情况下如果项目中有使用到第三方类库中的工具类的话我们都是采用这种方式注册Bean。
示例代码
public class Student {
}Configuration
public class AppConfig {Beanpublic Student student() {return new Student();}}public class Client {public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext new AnnotationConfigApplicationContext(AppConfig.class);System.out.println(applicationContext.getBean(student));}
}3FactoryBean方式
FactoryBean是一个Bean它允许我们自定义Bean的创建主要有三个方法
1、getObject()自定义Bean如何创建 2、getObjectType()要注册的Bean的类型 3、isSingleton()是否单例
示例代码
public class User {
}Component
public class UserFactoryBean implements FactoryBeanUser {Overridepublic User getObject() throws Exception {return new User();}Overridepublic Class? getObjectType() {return User.class;}Overridepublic boolean isSingleton() {return true;}
}Configuration
ComponentScan(com.koo. modules)
public class AppConfig {}public class Client {public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext new AnnotationConfigApplicationContext(AppConfig.class);System.out.println(applicationContext.getBean(userFactoryBean));System.out.println(applicationContext.getBean(userFactoryBean));}
}4Import方式
public class Student {
}Import({Student.class})
Configuration
public class AppConfig {}public class Client {public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext new AnnotationConfigApplicationContext(AppConfig.class);for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {System.out.println(beanDefinitionName);}System.out.println();System.out.println(applicationContext.getBean(com.koo.modules.entity.Student));System.out.println(applicationContext.getBean(student));}
}5Import ImportSelector方式
首先介绍一下ImportSelector接口的好处主要有以下两点 1、把某个功能的相关类放到一起方面管理和维护。 2、重写selectImports方法时能够根据条件判断某些类是否需要被实例化或者某个条件实例化这些bean其他的条件实例化那些bean等我们能够非常灵活的定制化bean的实例化。 public class Product {
}public class User {
}public class MyImportSelector implements ImportSelector {// 指定需要定义bean的类名注意要包含完整路径而非相对路径Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{com.koo.entity.Product, com.koo.entity.User};}}Import({MyImportSelector.class}) Configuration public class AppConfig {
} public class Client {public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext new AnnotationConfigApplicationContext(AppConfig.class);for (String beanDefinitionName : applicationContext.getBeanDefinitionNames()) {System.out.println(beanDefinitionName);} System.out.println(applicationContext.getBean(com.koo.entity.Product));try {System.out.println(applicationContext.getBean(product));} catch (Exception e) {e.printStackTrace();} System.out.println(applicationContext.getBean(com.koo.entity.User));try {System.out.println(applicationContext.getBean(user));} catch (Exception e) {e.printStackTrace();}}
}6Import ImportBeanDefinitionRegistrar方式
这种方式我们需要实现ImportBeanDefinitionRegistrar接口并重写registerBeanDefinitions()方法然后定义我们需要注册的Bean的定义信息然后registry.registerBeanDefinition()方法注册即可。这种方式比ImportSelector更加灵活可以自定义bean的名称、作用域等很多参数。 像我们常见的Spring Cloud中的Feign就使用了ImportBeanDefinitionRegistrar具体可以参考FeignClientsRegistrar类
public class User {
}public class Product {
}public class CustomImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {// 可以自定义bean的名称、作用域等很多参数registry.registerBeanDefinition(user, new RootBeanDefinition(User.class));RootBeanDefinition rootBeanDefinition new RootBeanDefinition(Product.class);rootBeanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);registry.registerBeanDefinition(product, rootBeanDefinition);}
}Import({CustomImportBeanDefinitionRegistrar.class})
Configuration
public class AppConfig {}public class Client {public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext new AnnotationConfigApplicationContext(AppConfig.class);System.out.println(applicationContext.getBean(product));System.out.println(applicationContext.getBean(user));}
}7BeanDefinitionRegistryPostProcessor方式
在Spring容器启动方法refresh()方法的invokeBeanFactoryPostProcessors()方法中会执行 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry()方法它允许对beanDefinition进行后置处理我们可以在这个方法调整IOC容器中的beanDefinition定义信息从而干扰到后面bean初始化的过程。
具体代码如下
public class User {
}Component
public class CustomBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {registry.registerBeanDefinition(user, new RootBeanDefinition(User.class));}Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {}
}Configuration
ComponentScan(com.koo.modules)
public class AppConfig {}public class Client {public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext new AnnotationConfigApplicationContext(AppConfig.class);System.out.println(applicationContext.getBean(user));}
}8BeanFactoryPostProcessor方式
其实BeanDefinitionRegistryPostProcessor就是继承自BeanFactoryPostProcessor所以使用BeanFactoryPostProcessor也可以实现注册Bean的功能。它们的区别如下
1、 BeanDefinitionRegistryPostProcessor侧重于bean的注册 2、 BeanFactoryPostProcessor侧重于对已经注册的bean的属性进行修改虽然也可以注册bean
public class Product {
}Component
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {DefaultListableBeanFactory registry (DefaultListableBeanFactory) beanFactory;registry.registerBeanDefinition(product, new RootBeanDefinition(Product.class));}
}Configuration
ComponentScan(com.koo.modules)
public class AppConfig {}public class Client {public static void main(String[] args) {AnnotationConfigApplicationContext applicationContext new AnnotationConfigApplicationContext(AppConfig.class);System.out.println(applicationContext.getBean(product));}
}3、基于Java类的方式
1.使用Configuration注解需要作为配置的类表示该类将定义Bean的元数据 2.使用Bean注解相应的方法该方法名默认就是Bean的名称该方法返回值就是Bean的对象。 3.AnnotationConfigApplicationContext或子类进行加载基于java类的配置
Configuration
public class BeansConfiguration { Bean public Student student(){ Student studentnew Student(); student.setName(张三); student.setTeacher(teacher()); return student; } Bean public Teacher teacher(){ Teacher teachernew Teacher(); teacher.setName(李四); return teacher; }
}
public class Client{ public static void main(String args[]){ AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext(BeansConfiguration.class); Student student (Student) context.getBean(student);Teacher teacher (Teacher) context.getBean(teacher);System.out.println(学生的姓名 student.getName() 。老师是 student.getTeacher().getName()); System.out.println(老师的姓名 teacher.getName()); } } 示例源码https://gitee.com/charlinchenlin/koo-erp