AspectJ之@DeclareParents注解为对象添加新方法

   众所周知,AspectJ可以通过@Before,@After,@Around等注解对连接点进行增强,今天我们来玩一个新注解@DeclareParents。对目标对象增强一个新方法。

  • 场景引入:

    现在我们有一个动物鸭子类,它有个游泳的函数,但是突然有一天我们需要给动物鸭子实现一个很好吃的食材属性。我们当然可以去动物鸭子类去新增一个方法,但是违背了单一原则。我们可以通过AOP来实现增强。

  • Code show time

  有一个Animal的接口

public interface Animal {

    void swim();
}

  再来一个动物鸭子的实现类

@Repository("animal")
public class DuckAnimal implements Animal{
    @Override
    public void swim() {
        System.out.println("鸭子喜欢游泳。。。");
    }
}

  需要一个增强方法,实现鸭子是一种美味的食物

public interface Food {
    void eat();
}

@Repository("food")
public class DuckFood implements Food{
    @Override
    public void eat() {
        System.out.println("鸭子看起来很好吃。。。");
    }
}

  采用自动注入

@ComponentScan("com.zjt.springboot.DeclareParents")
@Configuration
@EnableAspectJAutoProxy
public class AppConfiguration {
}

  声明一个切面

@Aspect
@Component
public class MyAspect {

    /**
     * com.zjt.springboot.DeclareParents.Animal+ 表示增强Animal的所有子类
     *
     *defaultImpl=DuckFood.class 表示默认需要添加的新类
     */
    @DeclareParents(value="com.zjt.springboot.DeclareParents.Animal+", defaultImpl=DuckFood.class)
    public static Food food;
}

  接下来就是紧张刺激的测试环节了:

public class Test {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext(AppConfiguration.class);
        Animal animal = (Animal)context.getBean("animal");
        animal.swim();
        Food food = (Food)animal;
        food.eat();

    }
}

测试结果:

鸭子喜欢游泳。。。
鸭子看起来很好吃。。。

结论:从测试结果我们发现,只从容器里获取了一个动物鸭子,却可以得到食材的功能,实现了增强功能!

原文地址:https://www.cnblogs.com/zjting/p/12540546.html

时间: 2024-08-26 13:05:41

AspectJ之@DeclareParents注解为对象添加新方法的相关文章

spring AOP Bean添加新方法

目的:为studentAdditionalDetails中添加Student的showDetails()和ExtraShowDetails()两个方法 spring  中AOP能够为现有的方法添加额外的功能,AOP也能为Spring Bean添加新方法 <aop:declare-parents types-matching="之前原始的类/接口" implement-interface="想要添加的功能的接口" defalut-impl="新概念的默

向Java枚举类型中添加新方法

除了不能继承enum之外,可将其看做一个常规类.甚至可以有main方法. 注意:必须先定义enum实例,实例的最后有一个分号. 下面是一个例子:返回对实例自身的描述,而非默认的toString返回枚举实例的名字. public enum Color { RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4); // 成员变量 private String nam

你会如何给全局对象添加toString()方法

首先,在讨论如何给所有方法window对象添加tostring方法的时候,我们先来说说window的对象继承与对象实例,以及构造函数的this指针,还有变量的提升与方法的调用方式,最终一探window对象与Window方法(函数)的处理方式. 在说window对象之前,请让我们一起写一个实例的方法暖暖身,跳水之前应该做热身动作,虽然我们不跳水,不过写代码也需要做一个热身,这样才能适应下面的高难度动作. 废话好多,裁判看不下去了,开始准备你的姿势,让我们开场就拿个满分,吓死裁判,但是看到裁判吓到自

为system对象添加扩展方法

////扩展方法类:必须为非嵌套,非泛型的静态类 public static class DatetimeEx { //通过this声明扩展的类,这里给DateTime类扩展一个Show方法,只有一个参数 public static void Show(this DateTime date, string msg) { Console.WriteLine("扩展方法调用"); Console.WriteLine(msg); } }

JS创建类和对象(好多方法哟!)

http://www.cnblogs.com/tiwlin/archive/2009/08/06/1540161.html 这是别人写的~~~我借来看看 JavaScript 创建类/对象的几种方式 在JS中,创建对象(Create Object)并不完全是我们时常说的创建类对象,JS中的对象强调的是一种复合类型,JS中创建对象及对对象的访问是极其灵活的. JS对象是一种复合类型,它允许你通过变量名存储和访问,换一种思路,对象是一个无序的属性集合,集合中的每一项都由名称和值组成(听起来是不是很像

给jquery对象添加自定义方法和扩展jquery类

http://blog.sina.com.cn/s/blog_944b24ef0101epr5.html 一.给jQuery对象添加自定义方法   方法一.$.fn.xxx 方法二.jQuery.fn.extend({ xxx:function(){ alert($(this).val()); } });       方法一示例: $.fn.setCursorPosition = function(position){            if(this.lengh == 0) return

为对象添加一个新的方法

例定义一个方法,为Date对象添加一个新的成员方法,转换为形如 y-m-d<br>h:m:s Date.prototype.stringify = function(){ var s= this.getFullYear()+'-'; s+= (this.getMonth()+1)+'-'; s+= this.getDate()+' '; s+= this.getHours()+':'; s+= this.getMinutes()+':'; s+= this.getSeconds(); retu

JavaScript之jQuery-9 jQuery 开发插件(添加新全局函数、添加jQuery对象方法、添加新简写方法、方法参数)

一.添加新的全局函数 全局函数 - 全局函数,实际上就是jQuery对象的方法,从实践角度看,它们是位于jQuery命名空间内部的函数 - jQuery内置的某些功能是通过全局函数实现的 - $.ajax()函数就是典型的全局函数 - 向jQuery命名空间添加一个函数,只需要将这个新函数指定为jQuery的一个属性值   - 如果要使用该全局函数时,可通过一下代码调用 - 也可以通过别名来调用 添加多个函数 - 如果我们想在插件中提供多个全局函数,可以独立的声明这些函数   - 还可以使用$.

解决 ko mapping 数组无法添加新对象的问题

这两天页面模板化的进程有些放缓,使用 ko mapping 插件的情形多了起来.组员经常问到的问题即是往 ko mapping 数组添加新对象时,报找不到方法的错误:而使用 ko.observableArray 创建的数组则可以随意添加或删除对象,这简直奇葩问题.好吧,不管怎样,总要解决问题的. // 数组定义 var ViewModelArray = ko.mapping.fromJS([]); <!--绑定文本--> <ul data-bind="foreach:$data