Java EE6装饰器:在注入时装饰类

软件中常见的设计模式是装饰器模式 。 我们上一堂课,然后在它周围包装另一堂课。 这样,当我们调用类时,我们总是在到达内部类之前经过周围的类。

Java EE 6允许我们通过CDI创建装饰器,作为其AOP功能的一部分。 如果我们想实现仍然与业务足够接近的跨领域关注点 ,则可以使用Java EE 6的此功能。

假设您有一项票务服务,可让您订购特定事件的票务。 TicketService处理注册等,但是我们要添加餐饮。 我们不认为这是门票订购逻辑的一部分,因此我们创建了一个装饰器。 装饰者将调用TicketService并添加门票数量。

界面:

public interface TicketService {
    Ticket orderTicket(String name);
}

接口的实现,创建票证并将其保留。

@Stateless
public class TicketServiceImpl implements TicketService {
 
    @PersistenceContext
    private EntityManager entityManager;
 
    @TransactionAttribute
    @Override
    public Ticket orderTicket(String name) {
        Ticket ticket = new Ticket(name);
        entityManager.persist(ticket);
        return ticket;
    }
}

当我们不能使用装饰器时,我们可以创建相同接口的新实现。

@Decorator
public class TicketServiceDecorator implements TicketService {
 
    @Inject
    @Delegate
    private TicketService ticketService;
    @Inject
    private CateringService cateringService;
 
    @Override
    public Ticket orderTicket(String name) {
        Ticket ticket = ticketService.orderTicket(name);
        cateringService.orderCatering(ticket);
        return ticket;
    }
}

请注意,我们在此处应用了2个CDI特定注释。 @Decorator将实现标记为装饰器。 装饰器应始终具有一个委托(我们要装饰的类),该委托带有@Delegate批注(在注入点处)标记。 还要注意我们使用接口而不是实现的事实。

就像其他示例一样 ,当您注入此接口时,将使用常规实现。

@Inject private TicketService ticketService;

无需使用限定符,我们只需要调整beans.xml即可将TicketServiceDecorator标记为“ Decorator”。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
    <decorators>
        <class>be.styledideas.blog.decorator.TicketServiceDecorator</class>
    </decorators>
</beans>

作为更高级的用法,我们可以组合多个装饰器并选择我们希望它们执行的顺序。

如果您有用例,则可以像这样在bean.xml文件中定义两个装饰器,从而轻松定义它们。

<decorators>
    <class>be.styledideas.blog.decorator.HighDecorator</class>
    <class>be.styledideas.blog.decorator.LowDecorator</class>
</decorators>

因此,当我们调用装饰类时,我们会得到高级装饰器条目,低装饰器条目,实际装饰器类,低装饰器出口,高装饰器出口。 因此,文件中的装饰器顺序确实很重要。

第二个功能比第一个功能更具吸引力,它展示了Java EE6中Decorator功能的真正威力。 这是将其与CDI批注结合在一起的能力。 作为示例,我将使用社交媒体供稿处理器。

所以我创建了一个接口:

public interface SocialFeedProcessor {
    Feed process(String feed);
}

并提供了2种实现,twitter和google +

public class TwitterFeedProcessor implements SocialFeedProcessor{
 
    @Override
    public Feed process(String feed) {
        System.out.println("processing this twitter feed");
        // processing logics
        return new Feed(feed);
    }
 
}
public class GooglePlusFeedProcessor implements SocialFeedProcessor {
 
    @Override
    public Feed process(String feed) {
        System.out.println("processing this google+ feed");
        // processing logics
        return new Feed(feed);
    }
 
}

我将按照此处所述通过自定义限定符对这2个bean进行注释

@javax.inject.Qualifier
@java.lang.annotation.Retention(RUNTIME)
@java.lang.annotation.Target({FIELD, PARAMETER, TYPE})
@java.lang.annotation.Documented
public @interface FeedProcessor {
}

然后用它注释我的两个处理器。

@FeedProcessor
public class TwitterFeedProcessor implements SocialFeedProcessor{
 
    @Override
    public Feed process(String feed) {
        System.out.println("processing this twitter feed");
        // processing logics
        return new Feed(feed);
    }
 
}
@FeedProcessor
public class GooglePlusFeedProcessor implements SocialFeedProcessor {
 
    @Override
    public Feed process(String feed) {
        System.out.println("processing this google+ feed");
        // processing logics
        return new Feed(feed);
    }
 
}

没什么特别的,但是现在当我们编写装饰器时,我们使用CDI的功能仅用@FeedProcessor注释装饰类。

@Decorator
public class SocialFeedDecorator implements SocialFeedProcessor {
    @Delegate
    private @FeedProcessor SocialFeedProcessor processor;
 
    @Override
    public Feed process(String feed) {
        System.out.println("our decorator is decorating");
        return processor.process(feed);
    }
}

剩下的唯一事情就是在beans.xml中注册装饰器

<decorators>
    <class>be.styledideas.blog.decorator.SocialFeedDecorator</class>
</decorators>

通过使用注释,我们可以使用该装饰器自动装饰我们的SocialfeedProcessor的所有实现。 当我们添加不带注释的SocialFeedProcessor的额外实现时,将不装饰Bean。

参考: Java EE6装饰器,在注入时装饰类, Java EE6装饰器,来自Styled Ideas Blog的 JCG合作伙伴 Jelle Victoor的 高级用法

相关文章 :

翻译自: https://www.javacodegeeks.com/2011/10/java-ee6-decorators-decorating-classes.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值