1. 介绍

在 CDI(Contexts and Dependency Injection)中,@Decorator 注解用于定义装饰器。装饰器是一种设计模式,允许你在不修改现有代码的情况下,动态地向对象添加新的功能。通过使用装饰器,你可以增强 Bean 的行为,而不需要直接修改 Bean 的实现。下面我用一个简单的例子来解释装饰器的概念和用法。

2. 定义接口 Shape

首先,定义一个接口 Shape,其中包含一个 draw 方法。所有实现该接口的类都需要实现这个方法。

package org.acme.decorator;

public interface Shape {
    String draw();
}

3. 实现 Shape 接口的 Bean

接下来,实现 Shape 接口的两个 Bean:Circle 和 Rectangle。

3.1 Circle 类

package org.acme.decorator;

import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class Circle implements Shape {
    @Override
    public String draw() {
        return "circle";
    }
}

3.2 Rectangle 类

package org.acme.decorator;

import jakarta.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class Rectangle implements Shape {
    @Override
    public String draw() {
        return "rectangle";
    }
}

4. 定义装饰器

使用 @Decorator 注解定义一个装饰器 BlueShapeDecorator,该装饰器将向 Shape 的 draw 方法添加 "Blue " 前缀。

package org.acme.decorator;

import jakarta.decorator.Decorator;
import jakarta.decorator.Delegate;
import jakarta.enterprise.inject.Any;
import jakarta.inject.Inject;

@Decorator
public class BlueShapeDecorator implements Shape {
    @Inject
    @Delegate
    @Any
    private Shape shape;

    @Override
    public String draw() {
        return "Blue " + shape.draw();
    }
}
  1. @Decorator 注解:用于标记 BlueShapeDecorator 类为一个装饰器。
  2. BlueShapeDecorator 实现了 Shape 接口,因此它可以装饰任何实现了 Shape 接口的 Bean。
  3. @Inject 注解用于依赖注入。
  4. @Delegate 注解标记一个字段 shape,该字段引用被装饰的 Bean。
  5. @Any 注解表示可以匹配任何 Shape 类型的 Bean。
  6. 在 draw 方法中,调用 shape.draw() 方法,并在其结果前添加 "Blue ",从而增强 Shape 的行为。

5. 使用 Shape Bean 并观察装饰器的效果

最后,编写一个主类来使用 Shape Bean,并观察装饰器的效果。

package com.aijiasoft.decorator;

import org.jboss.logging.Logger;
import io.quarkus.runtime.QuarkusApplication;
import io.quarkus.runtime.annotations.QuarkusMain;
import jakarta.inject.Inject;

@QuarkusMain
public class Main implements QuarkusApplication {
    private final static Logger logger = Logger.getLogger(Main.class);
    @Inject
    private Circle circle;
    @Inject
    private Rectangle rectangle;

    @Override
    public int run(String... args) throws Exception {
        logger.info(circle.draw());
        logger.info(rectangle.draw());
        return 0;
    }
}

由于 BlueShapeDecorator 装饰了 Circle 和 Rectangle Bean,调用 draw 方法时,实际上调用了 BlueShapeDecorator 的 draw 方法,输出结果为 "Blue circle" 和 "Blue rectangle"

源码下载

源码下载

posted on 2025-03-18 22:00  爱吃青菜的虫子  阅读(23)  评论(0)    收藏  举报