如何正确地使用基于Spring继承的代理配置? [英] How to exactly work the Spring Inheritance-based Proxies configuration?

查看:202
本文介绍了如何正确地使用基于Spring继承的代理配置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究Spring Core认证,我发现了一些与代理概念有关的疑问。



所以在研究资料我发现以下测验:



有一个Java 配置类包含以下方法:

  @Bean 
public AccountRepository accountRepository(){
return new JdbcAccountRepository();
}

@Bean
public TransferService transferService1(){
TransferServiceImpl service = new TransferServiceImpl();
service.setAccountRepository(accountRepository());
退货服务;
}

@Bean
public TransferService transferService2(){
return new TransferServiceImpl(new JdbcAccountRepository());
}

正如你所看到的那样,有两个不同的分别命名为 transferService1() transferService2(),创建并返回一个 TransferServiceImpl 对象。



第一个创建一个新的 TransferServiceImpl 对象,然后调用 setAccountRepository()方法。



第二个只是创建一个传递一个新的 JdbcAccountRepository 对象到其构造函数的 TransferServiceImpl



请问我**以前的两种方法中最好的实现是什么?



提供的答案是:喜欢调用专用方法< STRONG>。所以我认为最好的方法是第一个实现。



它解释说, AccountRepository bean是一个单例(因为它是Spring中的bean的标准范围),而且可以调用 JdbcAccountRepository()两次或更多次(例如在之前的代码片段中,称为方法 transferService1() transferService2(),如果是这样,这是一个问题,因为 AccountRepository 必须是一个单例



是真的吗?还是我错过了什么?



所以我在启动时收集foreach配置类(用 @Configuration 注释)创建一个扩展我的配置类的子类



例如如果我有以下配置类:

  @Configuration 
public class AppConfig {
@Bean public AccountRepository accountRepository(){...}
@Bean public TransferService transferService(){...}
}

它自动创建以下类,扩展了我的 AppConfig

  public class AppConfig $$ EnhancerByCGLIB $ extends AppConfig {
public AccountRepository accountRepository(){// ...}
public TransferService transferService(){//。 ..}
...
...
...
}

所以子类是入口点(调用的方法是孩子类中定义的),伪代码将是这样的:

  public class AppConfig $$ EnhancerByCGLIB $ extends AppConfig {

public AccountRepository accountRepository(){
//如果bean在applicationContext中返回bean
// else调用super.accountRepository()并在上下文中存储bean
}

public TransferService transferService(){
//如果bean在applicationContext中,则返回bean
// else调用super.transferService ()和存储bean在上下文
}
}

所以它看起来很漂亮清楚Spring如何处理单例问题:它调用扩展配置类的代理类上的方法,如果请求的bean存在于applicationContext中,返回此bean,否则在创建该bean的超类中调用相同的方法新bean并将其放入应用程序上下文



根据代理模式,继承的正确含义还是我缺少某些东西? >

解决方案

是的,你所描述的基本上是如何 Spring手柄 @Configuration


全部 @Configuration 类在启动时使用
CGLIB进行子类化。在子类中,子方法在调用父方法之前首先检查任何缓存(作用域)bean的

创建一个新实例。


如果认证问题中的问题只有一个新JdbcAccountRepository()的实例,那么,是的,最好使用中的 accountRepository() @Bean @Configuration class。


I am studying for the Spring Core certification and I am finding some doubts related to the proxying notion.

So on the study material I find the following quiz:

There is a Java configuration class that contains the following methods:

@Bean
public AccountRepository accountRepository(){ 
    return new JdbcAccountRepository(); 
}

@Bean
public TransferService transferService1() {
    TransferServiceImpl service = new TransferServiceImpl();
    service.setAccountRepository(accountRepository());
    return service;
}

@Bean
public TransferService transferService2() {
    return new TransferServiceImpl( new JdbcAccountRepository() );
}

As you can see there are 2 different implementation of a transferService() respectively named as transferService1() and transferService2() that create and return a TransferServiceImpl object.

The first one creatre a new TransferServiceImpl object and then call the setAccountRepository() method on it.

The second one simply create a TransferServiceImpl passing a new JdbcAccountRepository object to its constructor.

It ask to me **Which is the best implementation brween the previous 2 methods?

And the answer provided is: Prefer call to dedicated method. So I think that it say that the best way is the first implementation.

It explain that AccountRepository bean is a singleton (because it is the standard scope for the beans in Spring) but that the JdbcAccountRepository() could be called twice or more times (for example in the previous code snippet it is called when are called the methods transferService1() and transferService2() and if so this would be a problem because AccountRepository have to be a singleton.

Is it true? Or am I missing something?

So I gather that at startup time foreach configuration class (annotated with @Configuration) is created a child class that extends my configuration class.

For example if I have the following configuration class:

@Configuration
public class AppConfig {
    @Bean public AccountRepository accountRepository() { ... }
    @Bean public TransferService transferService() { ... }
}

it is automatically created the following class that extends my AppConfig:

public class AppConfig$$EnhancerByCGLIB$ extends AppConfig {
    public AccountRepository accountRepository() { // ... }
    public TransferService transferService() { // ... }
    ...
    ...
    ...
}

So the child class is the entry point (the method called are those definied in the child class) and the pseudocode will be something like this:

public class AppConfig$$EnhancerByCGLIB$ extends AppConfig {

    public AccountRepository accountRepository() {
        // if bean is in the applicationContext return bean
        // else call super.accountRepository() and store bean in context
    }

    public TransferService transferService() {
        // if bean is in the applicationContext, return bean
        // else call super.transferService() and store bean in context
    }
}

So it appear pretty clear how Spring can handle the singleton problem: it call the methods on a proxy class that extends the configuration class and if the requested bean exist into the applicationContext return this beans, else call the same method on the super class that create the new bean and put it into the application context

Is it the right meaning of the inheritance based on the proxy pattern or am I missing something?

解决方案

Yes, what you've described is basically how Spring handles @Configuration classes

All @Configuration classes are subclassed at startup-time with CGLIB. In the subclass, the child method checks the container first for any cached (scoped) beans before it calls the parent method and creates a new instance.

If the problem in the certification question is to only have one instance of new JdbcAccountRepository(), then, yes, it is best to use the accountRepository() @Bean method within the @Configuration class.

这篇关于如何正确地使用基于Spring继承的代理配置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆