[Day - 12] - Spring 注入式效能提升运作与方法

Abstract

在开发的领域中,每个元件何时产生、何时建立新元件都是会影响效能,都是每个开发者会注重的议题,在前面启章叙述过,开发者采用Spring 框架时,必定有多种模式注解会注册进BeanFactory中,但何时才需要注册这个Bean元件,都会影响相关整个系统效率,此时懒注册(@Lazy)是各位开发者首要选择,进行分析某些元件非必要性,当有需求再建立,无需所有元件都注册进配置池进而影响效能,我们可通过原理与架构来进一步理解所该注解模式带给开发者提升效率层的效益。

Principle Introduction

在前面章节以叙述过注入Bean方法分为两种,一种为透过BeanFactory或子介面ApplicationContext两项元件进行读取XML元件进行注册,或透过模式注解进行元件扫描注册後,再次进行注入,第二种为透过注解进行注入,分为@Autowired或@Resource注解方式进行注入,大部分元件都是透过CommonAnnotationBeanPostProcessor此处理器元件进行过滤与获取,那如何进行分析与过滤懒注册(@Lazy)元件呢?可以看到透过getResourceToInject这方法中,如果是@Lazy注解,则是通过建构一个代理模式对象进行返回,否则直接调用getResource方法(如程序码区块一),那我们得知此注解所影响後续取得资源的效益过程有多少,提供开发者自行评估,透过我们所提供的范例建立了三个Apple、Android及BlackBerry三项服务元件,我们只有在Android服务上不配置Lazy注解,其他两项服务皆配置此注解,相关叙述我们从下面范例程序码可以得知。

程序法区块一

@Override
protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
    return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) :
            getResource(this, requestingBeanName));
}

配置@Lazy注解在服务上,并配置@PostConstruct注解在初始化过程中加上叙述,详细说明如下

@Lazy
@Primary
@Service("Apple")
public class ApplePhoneServiceImpl implements PhoneServcie  {

    @PostConstruct
    public void init() {
        System.out.println("With @Lazy : ApplePhoneServiceImpl initialize. ");
    }

    .......
    .......
    .......
    
}

未配置@Lazy注解在服务上,并配置@PostConstruct注解在初始化过程中加上叙述,详细说明如下

@Service("Android")
public class AndroidPhoneServiceImpl implements PhoneServcie  {

    @PostConstruct
    public void init() {
        System.out.println("Without @Lazy : AndroidPhoneServiceImpl initialize. ");
    }
    .....
    .....
    .....
    
}

根据PhoneTestSuite测试类别元件,可以得到相关结果,如下所示

public class PhoneTestSuite extends ServiceTestBase {

    @Resource(name = "Android",type = PhoneServcie.class)
    PhoneServcie androidPhoneServcie;


    PhoneServcie applePhoneService = null;

    @Autowired
    private ApplicationContext applicationContext;

    // 测试一般初始化的元件
    @Test
    public void testAndroidPhoneProductSizeTask() {
        assertEquals(androidPhoneServcie.listAllPhone().size(),6);
        System.out.println("Android vendor validate success.");
    }

    // 测试BlackBerry懒注册的元件
    @Test
    public void testBlackBerryPhoneProductSizeTask( ) {
        PhoneServcie blackBerryPhoneService = applicationContext.getBean("BlackBerry",PhoneServcie.class);
        assertEquals(blackBerryPhoneService.listAllPhone().size(),2);
        System.out.println("Black Berry vendor with lazy loading validate success.");
    }
    // 测试Apple懒注册的元件
    @Test
    public void testApplePhoneProductSizeTask( ) {
        PhoneServcie applePhoneService = applicationContext.getBean(PhoneServcie.class);
        assertEquals(applePhoneService.listAllPhone().size(),6);
        System.out.println("Apple vendor with lazy loading validate success.");
    }
}

再透过运作的Log中,我们可以看到只有没有被配置的AndroidPhoneServiceImpl类别元件有在初始化过程中被注册,其余两项元件都在有需要注册此元件时在进行注册,相关结果如下:

2021-08-26 00:07:30.878  INFO 10772 --- [    Test worker] sw.project.sample.PhoneTestSuite         : No active profile set, falling back to default profiles: default
Without @Lazy : AndroidPhoneServiceImpl initialize. 
2021-08-26 00:07:32.622  INFO 10772 --- [    Test worker] sw.project.sample.PhoneTestSuite         : Started PhoneTestSuite in 2.052 seconds (JVM running for 3.35)
With @Lazy : BlackBerryPhoneServiceImpl initialize. 
Black Berry vendor with lazy loading validate success.

透过以上原理介绍与示范,我们可以看出如何优化我们的开发系统与流程顺序是相当重要的一个步骤,开发者可以透过此篇文章作参考。

Structure

该注解原理相当简单,就只用来判定此资源是否为懒注册类型元件,判定是否取用代理对象进行获取对应元件,其判定值预设为true,其注解可运用在各种类别类型、方法、建构子或宣告参数之上,读者可透过以下图示所得之。

图一 @Lazy原理架构图
image

Follow up

Run test task

gradle test

Run open result html

open ./build/reports/tests/test/index.html

Test Report

Lazy loading test
image

Mind-blowing test detail
image

Sample Source

Spring-sample-lazy

Reference Url

@Lazy Reference code

Spring IOC(八)CommonAnnotationBeanPostProcessor 原理分析


<<:  Day 27 : 使用 TensorFlow Serving 部署 REST API

>>:  【Day 27】JavaScript 回呼函式(callback function)

[Day05 - UI/UX] 为APP制作 LOGO

要开始画一个LOGO之前我习惯先简单列出一些主题文字。这次要做的是一个旅游包包整理APP所以我列出下...

Day 31 | 常见 Livewire 问题: jQuery 在渲染时会打回原形

jQuery 在大多数的专案中都不可或缺,在没有 Livewire 之前要修改画面都要靠它来手动更改...

AI ninja project [day 9] 先验演算法

除了在机器学习与深度学习的演算法, 其实还有一些演算法,可以帮忙做资料整理, 或是进行推导,寻找关联...

Shayari for the day

motivation shayari to motivate and inspire. Shayar...

Aol Mail Not Working on iPhone Device

If AOL is not working on your iPhone, you can try ...