IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Spring教程动画文字版2 -> 正文阅读

[游戏开发]Spring教程动画文字版2

接上篇文章:https://blog.csdn.net/single_wolf_wolf/article/details/122948647

这个是笔者在B站看周瑜大神的相关视频时候的笔记
B站 周瑜大神

任意门:https://www.bilibili.com/video/BV1bY411b7Q6?p=48&spm_id_from=pageDriver


P37: @Resource注解你真的会用吗?

参考:[P5 @Resource如何工作的?](## P5 @Resource如何工作的?)

总览

  • 没有指定name:判断字段名字所对应的Bean是否存在,如果存在则把这个Bean赋值给属性,如果不存在则根据字段类型找Bean;
  • 指定了name:指定了名字,就只会根据名字去查询,找到就用,找不到就报错;
  • 注意:@Resource注解是JDK层面定义的,Spring负责实现,负责提供对于这个注解的支持

@Resource 和@Autowired注解都是用来依赖注入的。

P38 @Configuration你真的会用吗

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {

	/**
	 * Explicitly specify the name of the Spring bean definition associated with the
	 * {@code @Configuration} class. If left unspecified (the common case), a bean
	 * name will be automatically generated.
	 * <p>The custom name applies only if the {@code @Configuration} class is picked
	 * up via component scanning or supplied directly to an
	 * {@link AnnotationConfigApplicationContext}. If the {@code @Configuration} class
	 * is registered as a traditional XML bean definition, the name/id of the bean
	 * element will take precedence.
	 * @return the explicit component name, if any (or empty String otherwise)
	 * @see AnnotationBeanNameGenerator
	 */
	@AliasFor(annotation = Component.class)
	String value() default "";

	/**
	 * Specify whether {@code @Bean} methods should get proxied in order to enforce
	 * bean lifecycle behavior, e.g. to return shared singleton bean instances even
	 * in case of direct {@code @Bean} method calls in user code. This feature
	 * requires method interception, implemented through a runtime-generated CGLIB
	 * subclass which comes with limitations such as the configuration class and
	 * its methods not being allowed to declare {@code final}.
	 * <p>The default is {@code true}, allowing for 'inter-bean references' via direct
	 * method calls within the configuration class as well as for external calls to
	 * this configuration's {@code @Bean} methods, e.g. from another configuration class.
	 * If this is not needed since each of this particular configuration's {@code @Bean}
	 * methods is self-contained and designed as a plain factory method for container use,
	 * switch this flag to {@code false} in order to avoid CGLIB subclass processing.
	 * <p>Turning off bean method interception effectively processes {@code @Bean}
	 * methods individually like when declared on non-{@code @Configuration} classes,
	 * a.k.a. "@Bean Lite Mode" (see {@link Bean @Bean's javadoc}). It is therefore
	 * behaviorally equivalent to removing the {@code @Configuration} stereotype.
	 * @since 5.2
	 */
	boolean proxyBeanMethods() default true;

}

总览

被@Configuration注解修饰的类,首先是一个Bean,并且是一个配置Bean

什么是配置Bean?

proxyBeanMethods:代理Bean方法

  • 有@Configuration注解
    • proxyBeanMethods默认是true,表示是Full配置Bean;
    • proxyBeanMethodsfalse,表示是Lite配置Bean(lite Mode:精简模式);
  • 无@Configuration注解
    • 存在@Component注解就是Lite配置Bean;
    • 存在@ComponentScan注解就是Lite配置Bean;
    • 存在@Import注解就是Lite配置Bean;
    • 存在@ImportResource注解就是Lite配置Bean;
    • 存在@Bean注解的方法就是Lite配置Bean;

配置Bean有什么用?

对于配置Bean,不仅仅只是放入容器中,Spring还会去解析配置Bean,

  • 比如处理@ComponentScan就会去扫描
  • 比如处理@Import注解就会将某个类导入成为Bean;
  • 比如处理@Bean就会解析对应方法生成Bean;

proxyBeanMethods

  • true:配置Bean对应的配置类的代理对象
  • false:配置Bean对应的配置类的普通对象

举个例子,上文也提到过,为什么有的配置类是代理对象,有的却是普通对象:

@Configuration
public class AppConfig {
//这种情况下 是Full配置Bean,AppConfig是一个代理对象
//Lite配置Bean,AppConfig是一个普通对象
}

P39 @Import你真的会用吗?

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {

	/**
	 * {@link Configuration @Configuration}, {@link ImportSelector},
	 * {@link ImportBeanDefinitionRegistrar}, or regular component classes to import.
	 */
	Class<?>[] value();

}

总览

  • 普通类型:直接将该类当做Bean;
  • ImportSelector:将selectImport()方法返回的类当做Bean;
  • DeferredImportSelector
    • 将selectImport()方法返回的类当做Bean;
    • 与ImportSelector类型的却别在于selectImport()方法执行时机不同;
  • ImportBeanDefinitionRegistrar类型:在registerBeanDefinitions()方法中注册BeanDefinition;

把某个类导入Spring容器作为一个Bean(配置Bean

@ComponentScan(value = "com.zhouyu")
@Import(UserService.class)
public class AppConfig {
}

public class UserService {

}

public class MainTest {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        System.out.println(applicationContext.getBeanFactory().getBean(UserService.class));
        UserService userService = (UserService)applicationContext.getBean("userService");
        System.out.println(userService);
    }

}

执行一下:

com.zhouyu.springdemo.service.UserService@30f842ca
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'userService' available
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:816)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1288)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1109)
	at com.zhouyu.springdemo.service.MainTest.main(MainTest.java:16)

可以看到Spring容器里面是有UserService的Bean对象,至于报错,是因为这种导入方式的,Bean的name不再是默认的首字母小写也就是userService。

这个Import导入的Bean是配置Bean,也就是你可以再导入的类中定义Bean对象,比如@Bean,@ComponentScan。

举个例子

@Import(UserService.class)
public class AppConfig {
//去掉扫描注解

}

@Component
public class OrderService {

}

@ComponentScan(value = "com.zhouyu")
public class UserService {
//增加扫描路径
}

public class MainTest {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        System.out.println(applicationContext.getBeanFactory().getBean(UserService.class));
        System.out.println(applicationContext.getBeanFactory().getBean(OrderService.class));
    }

}

执行:

com.zhouyu.springdemo.service.UserService@2dfaea86
com.zhouyu.springdemo.service.OrderService@15888343

Process finished with exit code 0

可以看到扫描到了OrderService这个Bean了,这里就是UserService被@Import导入以后,被视作一个配置Bean,所以其上的@ComponentScan注解生效了。

P40 @Import导入之ImportSelector类型的作用

某个类(下面例子中的(ZhouyuImportSelector)实现ImportSelector接口,并且实现selectImports()方法,并且用@Import导入,那么这个类就会成为一个配置Bean,同时selectImports()方法,返回的字符串列表(类名称列表),里面的类都会成为Bean。

ImportSelector接口:

public interface ImportSelector {

	/**
	 * Select and return the names of which class(es) should be imported based on
	 * the {@link AnnotationMetadata} of the importing @{@link Configuration} class.
	 * @return the class names, or an empty array if none
	 */
	String[] selectImports(AnnotationMetadata importingClassMetadata);

	/**
	 * Return a predicate for excluding classes from the import candidates, to be
	 * transitively applied to all classes found through this selector's imports.
	 * <p>If this predicate returns {@code true} for a given fully-qualified
	 * class name, said class will not be considered as an imported configuration
	 * class, bypassing class file loading as well as metadata introspection.
	 * @return the filter predicate for fully-qualified candidate class names
	 * of transitively imported configuration classes, or {@code null} if none
	 * @since 5.2.4
	 */
	@Nullable
	default Predicate<String> getExclusionFilter() {
		return null;
	}

}

举个例子:

@Import(ZhouyuImportSelector.class)
public class AppConfig {}

public class OrderService {}

public class UserService {}

public class ZhouyuImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        //返回的类列表(类名称)会成为Bean
        return new String[]{OrderService.class.getName(),UserService.class.getName()};
    }
}

public class MainTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        //这种导入,名称不是默认的驼峰命名,所以用类型获取
        System.out.println(applicationContext.getBeanFactory().getBean(UserService.class));
        System.out.println(applicationContext.getBeanFactory().getBean(OrderService.class));
    }
}

结果:

com.zhouyu.springdemo.service.UserService@166fa74d
com.zhouyu.springdemo.service.OrderService@40f08448

Process finished with exit code 0

DeferredImportSelector接口和ImportSelector接口,这里类似,就是执行时机不一样

P41 @Import导入之ImportBeanDefinitionRegistrar 类型的作用

某个类(下面例子中的(ZhouyuImportBeanDefinitionRegistrar)实现ImportBeanDefinitionRegistrar接口,并且实现registerBeanDefinitions()方法,并且用@Import导入,那么这个类就会成为一个配置Bean,同时registerBeanDefinitions()方法,里面生成一个BeanDefinition,然后注册这个BeanDefinition到Spring容器中,就会生成这个Bean。

注意:Spring整合Mybatis的时候,就用到了这个原理,将mybatis的代理对象注册到Spring容器中的时候,就是这个方式。

ImportBeanDefinitionRegistrar接口:

public interface ImportBeanDefinitionRegistrar {

	/**
	 * Register bean definitions as necessary based on the given annotation metadata of
	 * the importing {@code @Configuration} class.
	 * <p>Note that {@link BeanDefinitionRegistryPostProcessor} types may <em>not</em> be
	 * registered here, due to lifecycle constraints related to {@code @Configuration}
	 * class processing.
	 * <p>The default implementation delegates to
	 * {@link #registerBeanDefinitions(AnnotationMetadata, BeanDefinitionRegistry)}.
	 * @param importingClassMetadata annotation metadata of the importing class
	 * @param registry current bean definition registry
	 * @param importBeanNameGenerator the bean name generator strategy for imported beans:
	 * {@link ConfigurationClassPostProcessor#IMPORT_BEAN_NAME_GENERATOR} by default, or a
	 * user-provided one if {@link ConfigurationClassPostProcessor#setBeanNameGenerator}
	 * has been set. In the latter case, the passed-in strategy will be the same used for
	 * component scanning in the containing application context (otherwise, the default
	 * component-scan naming strategy is {@link AnnotationBeanNameGenerator#INSTANCE}).
	 * @since 5.2
	 * @see ConfigurationClassPostProcessor#IMPORT_BEAN_NAME_GENERATOR
	 * @see ConfigurationClassPostProcessor#setBeanNameGenerator
	 */
	default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,
			BeanNameGenerator importBeanNameGenerator) {

		registerBeanDefinitions(importingClassMetadata, registry);
	}

	/**
	 * Register bean definitions as necessary based on the given annotation metadata of
	 * the importing {@code @Configuration} class.
	 * <p>Note that {@link BeanDefinitionRegistryPostProcessor} types may <em>not</em> be
	 * registered here, due to lifecycle constraints related to {@code @Configuration}
	 * class processing.
	 * <p>The default implementation is empty.
	 * @param importingClassMetadata annotation metadata of the importing class
	 * @param registry current bean definition registry
	 */
	default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
	}

}

举个例子:

@Import(ZhouyuImportBeanDefinitionRegistrar.class)
public class AppConfig {
}

public class OrderService {
}

public class ZhouyuImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    //注册一个BeanDefinitions  也就是一个Bean
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,
                                        BeanNameGenerator importBeanNameGenerator) {
        //生成一个BeanDefinition
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition();
        AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
        //指定类
        beanDefinition.setBeanClass(OrderService.class);
        //注册到Spring容器中,这里可以指定beanName
        registry.registerBeanDefinition("orderService",beanDefinition);
    }
}

public class MainTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        System.out.println(applicationContext.getBeanFactory().getBean(OrderService.class));
    }
}

结果:

16:16:09.978 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'appConfig'
16:16:09.984 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'orderService'
com.zhouyu.springdemo.service.OrderService@71623278

Process finished with exit code 0

P42 @Lookup注解你真的会用吗

抽象类因为无法实例化,所以如果在抽象类上面增加@Component类似的注解,不会生成一个Bean。

举个例子:

@Component
public abstract class AbstractBeanTest {

    public abstract  OrderService test();

}

public class MainTest {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        System.out.println(applicationContext.getBeanFactory().getBean(AbstractBeanTest.class));
    }
}

结果:

Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.zhouyu.springdemo.service.AbstractBeanTest' available
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:351)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
	at com.zhouyu.springdemo.service.MainTest.main(MainTest.java:16)

Process finished with exit code 1

如果这个抽象类的方法上面增加了,@Lookup注解,那么这个抽象类就会生成一个Bean,其实是一个CGLIB动态代理对象。

此外:

Spring提供了一个名为@Lookup的注解,这是一个作用在方法上的注解,被其标注的方法会被重写,然后根据其返回值的类型,容器调用BeanFactory的getBean()方法来返回一个bean

还是上面的例子:

@Component
public class OrderService {
}

@Component
public abstract class AbstractBeanTest {

    @Lookup("orderService")
    public   OrderService test(){
        return null;
    }

}

public class MainTest {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        AbstractBeanTest abstractBeanTest = (AbstractBeanTest)applicationContext.getBean("abstractBeanTest");
        System.out.println(abstractBeanTest);
        System.out.println(abstractBeanTest.test());
    }
}

结果:

com.zhouyu.springdemo.service.AbstractBeanTest$$EnhancerBySpringCGLIB$$355b93b0@491b9b8
com.zhouyu.springdemo.service.OrderService@1a4927d6

Process finished with exit code 0

可以看到AbstractBeanTest的一个cglib的动态代理对象。

总览

  • @Lookup注解的作用在官网上叫做方法注入
  • @Autowired、@Resource、@Value是属性注入,是给某个属性赋值
  • @Lookup注解的作用是给某个方法赋值一个Bean,所以叫做方法注入(和Set方法,构造方法注入做区分),在调用这个方法是会返回所指定的Bean对象
  • 正常情况下抽象类是不能成为Bean对象的,但是如果抽象类中的抽象方法用了@Lookup注解,那么最终也能产生一个Bean对象,并且该Bean对象可以调用抽象方法,并返回所指定的Bean对象。
  • methodReplacer ------- 方法替换器

P43 @Primary注解你真的会用吗

在Spring容器中可能会存在一个类型的多个Bean对象,这时可以通过在某个Bean对象上使用@Primary注解来标识该Bean作为这个类型下的主Bean,在依赖注入时会优先使用。

P44 注册一个Bean有哪些方式?

总览

  • @Component
    • @Configuration
    • @Service
    • @Controller
    • @Repository
  • @Bean:通过解析某个方法作为Bean
  • @Import:导入类或BeanDefinition作为Bean
  • @ImportResource:导入一个spring.xml文件,通过解析该文件注册Bean
  • BeanDefinitionRegistryPostProcessor:通过注册BeanDefinition来注册Bean
  • FactoryBean:------SmartFactoryBean ------- 将自己new的对象注册为Bean
  • applicationContext.registerBean():通过Supplier接口来提供一个对象作为Bean
  • applicationContext.register():直接将某个类注册为Bean
  • applicationContext.registerBeanDefinition():注册一个BeanDefinition,就相当于注册了一个Bean

BeanDefinitionRegistryPostProcessor举个例子:通过生成一个BeanDefinition来注册一个Bean

//这里要指定这个实现了BeanDefinitionRegistryPostProcessor接口的类是一个Bean
@Component
public class ZhouyuBeanDefinitionRegistryPostProcessor  implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition();
        AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
        beanDefinition.setBeanClass(UserService.class);
        registry.registerBeanDefinition("userService",beanDefinition);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

    }
}

public class UserService {

}

public class MainTest {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        System.out.println(applicationContext.getBean("userService"));
    }
}

//结果:
11:15:45.531 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'userService'
com.zhouyu.springdemo.service.UserService@6f43c82

Process finished with exit code 0

P45 FactoryBean注册Bean的方式

看例子,ZhouyuFactoryBean这个name里面打印的对象实际是UserService的Bean对象,这里要注意,可以通过修改@Component里面的value属性来修改bean的name

//可以通过修改@Component里面的value属性来修改bean的name
@Component
public class ZhouyuFactoryBean implements FactoryBean {
    @Override
    public Object getObject() throws Exception {
        return new UserService();
    }

    @Override
    public Class<?> getObjectType() {
        return UserService.class;
    }
}
//上面的类是有两个Bean:ZhouyuFactoryBean这个Bean对象,UserService的Bean对象

public class UserService {
}

public class MainTest {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        System.out.println(applicationContext.getBean("zhouyuFactoryBean"));
    }
}

//结果:
com.zhouyu.springdemo.service.UserService@3932c79a

Process finished with exit code 0

如果这个时候的UserService里面注入了一个Bean,这个Bean是null。

另外,如果上面的代码修改为

System.out.println(applicationContext.getBean("&zhouyuFactoryBean"));

注意,中间多了一个“&”,那么或获取ZhouyuFactoryBean这个Bean的Bean对象而不是UserService的Bean对象。

结果:

com.zhouyu.springdemo.service.ZhouyuFactoryBean@3932c79a

Process finished with exit code 0

P46 SmartFactoryBean定义Bean方式

debug可以发现实现FactoryBean 接口的时候,getObject()并不是在Spring容器启动的时候初始化阶段调用的,而是在执行

System.out.println(applicationContext.getBean("zhouyuFactoryBean"));

这个命令的时候,才调用的,也就是类似懒加载的情况。

SmartFactoryBean子接口集成了 FactoryBean接口,其中的方法isEagerInit()可以指定是否在Spring容器启动的时候加载这个Bean,默认是false。

public interface SmartFactoryBean<T> extends FactoryBean<T> {

	/**
	 * Is the object managed by this factory a prototype? That is,
	 * will {@link #getObject()} always return an independent instance?
	 * <p>The prototype status of the FactoryBean itself will generally
	 * be provided by the owning {@link BeanFactory}; usually, it has to be
	 * defined as singleton there.
	 * <p>This method is supposed to strictly check for independent instances;
	 * it should not return {@code true} for scoped objects or other
	 * kinds of non-singleton, non-independent objects. For this reason,
	 * this is not simply the inverted form of {@link #isSingleton()}.
	 * <p>The default implementation returns {@code false}.
	 * @return whether the exposed object is a prototype
	 * @see #getObject()
	 * @see #isSingleton()
	 */
	default boolean isPrototype() {
		return false;
	}

	/**
	 * Does this FactoryBean expect eager initialization, that is,
	 * eagerly initialize itself as well as expect eager initialization
	 * of its singleton object (if any)?
	 * <p>A standard FactoryBean is not expected to initialize eagerly:
	 * Its {@link #getObject()} will only be called for actual access, even
	 * in case of a singleton object. Returning {@code true} from this
	 * method suggests that {@link #getObject()} should be called eagerly,
	 * also applying post-processors eagerly. This may make sense in case
	 * of a {@link #isSingleton() singleton} object, in particular if
	 * post-processors expect to be applied on startup.
	 * <p>The default implementation returns {@code false}.
	 * @return whether eager initialization applies
	 * @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory#preInstantiateSingletons()
	 */
	default boolean isEagerInit() {
		return false;
	}

}

P47 ApplicationContext注册Bean的三种方式

applicationContext.register()

例子:

public class UserService {
        @Autowired
    private OrderService orderService;

    public void test(){
        System.out.println(orderService);
    }
}

@Component
public class OrderService {
}

public class MainTest {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        applicationContext.register(UserService.class);
        UserService userService =(UserService) applicationContext.getBean("userService");
        System.out.println(userService);
        userService.test();
    }
}

//结果:
:01.028 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'userService'
com.zhouyu.springdemo.service.UserService@20b2475a
com.zhouyu.springdemo.service.OrderService@7857fe2

Process finished with exit code 0

applicationContext.registerBean()

例子:OrderService UserService保持不变

public class MainTest {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        //applicationContext.register(UserService.class);
        applicationContext.registerBean("userService", UserService.class, new Supplier<UserService>() {
            @Override
            public UserService get() {
                return new UserService();
            }
        });
        UserService userService =(UserService) applicationContext.getBean("userService");
        System.out.println(userService);
        userService.test();
    }
}

//结果:
14:34:09.454 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'userService'
com.zhouyu.springdemo.service.UserService@821330f
com.zhouyu.springdemo.service.OrderService@6f43c82

Process finished with exit code 0

这种方式和FactoryBean注册的Bean的区别就是UserService这个Bean里面的注入的属性:OrderService是有值的

applicationContext.registerBeanDefinition()

例子:

public class MainTest {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        //applicationContext.register(UserService.class);
 /*       applicationContext.registerBean("userService", UserService.class, new Supplier<UserService>() {
            @Override
            public UserService get() {
                return new UserService();
            }
        });*/
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        beanDefinition.setBeanClass(UserService.class);
        applicationContext.registerBeanDefinition("userService",beanDefinition);

        UserService userService =(UserService) applicationContext.getBean("userService");
        System.out.println(userService);
        userService.test();
    }
}

//结果:
14:36:52.413 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'userService'
com.zhouyu.springdemo.service.UserService@5db6b9cd
com.zhouyu.springdemo.service.OrderService@210ab13f

Process finished with exit code 0

未完待续

仅学习使用,侵权速删!

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-03-06 13:29:43  更:2022-03-06 13:30:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 16:50:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码