1. 程式人生 > 其它 >Spring AOP(二)@within() 和 @target

Spring AOP(二)@within() 和 @target

技術標籤:AOP&反射

如果多個類使用了多個註解,而且類之間有繼承關係,那AOP效果就熱鬧了!以下圖為例,Human類使用A1註解,Man類使用A2註解,Boy類沒有顯式使用註解。
在這裡插入圖片描述

形象比喻

@within() 和 @target的“作用域”有點像清朝的爵位和官位的“有效期”:

  • @within() ,類似於爵位,是可以世襲的,老子跟著皇上出生入死,被分封的爵位兒子可以世襲,這叫封妻廕子。
  • @target(),類似於官位,是不能世襲的,紈絝子弟,是不能讓他做官的。
@Before("@target(com.javatpoint.jjk.A1)")
public
void execute2() { System.out.println("@target --- A1"); }

上述程式碼可以形象地理解為,誰的官位是A1,就在他的所有方法執行前進行增強,即列印@target — A1,顯然,只有Human被封了官。這種官位是不能世襲的,所以,對Man和Boy無效。

@Before("@within(com.javatpoint.jjk.A2)")
public void execute3() {
    System.out.println("@within --- A2");
}

上述程式碼可以形象地理解為,誰是A2爵位的受益者,就在他自己的方法,或者繼承的方法執行前增強,即列印@within — A2,顯然,Man、Boy都收益。Boy重寫的方法不會增強,這不是世襲的,也好理解!

完整程式碼

package com.javatpoint.jjk;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention
(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface A1 { }
package com.javatpoint.jjk;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface A2 {
}
package com.javatpoint.jjk;

@A1
public class Human {
    public void say(String sentence) {
        System.out.println("Human says:" + sentence);
    }

    public void run() {
        System.out.println("Human runs." );
    }

    public void jump() {
        System.out.println("Human jump." );
    }
}
package com.javatpoint.jjk;

@A2
public class Man extends Human{
    @Override
    public void run() {
        System.out.println("Man runs." );
    }

    public void testMan() {
        System.out.println("Man testMan." );
    }
}
package com.javatpoint.jjk;

public class Boy extends Man {
    @Override
    public void jump() {
        System.out.println("Boy jump." );
    }

    public void test() {
        System.out.println("Bot test...");
    }
}
package com.javatpoint.jjk;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class HumanAspect 
    @Before("@within(com.javatpoint.jjk.A1)")
    public void execute1() {
        System.out.println("@within --- A1");
    }

    @Before("@target(com.javatpoint.jjk.A1)")
    public void execute2() {
        System.out.println("@target --- A1");
    }

    @Before("@within(com.javatpoint.jjk.A2)")
    public void execute3() {
        System.out.println("@within --- A2");
    }

    @Before("@target(com.javatpoint.jjk.A2)")
    public void execute4() {
        System.out.println("@target --- A2");
    }
}
package com.javatpoint.jjk;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@ComponentScan("com.javatpoint.jjk")
@EnableAspectJAutoProxy
public class HumanManager {
    @Bean(name = "human")
    public Human getHuman() {
        return new Human();
    }

    @Bean(name = "man")
    public Man getMan() {
        return new Man();
    }

    @Bean(name = "boy")
    public Boy getBoy() {
        return new Boy();
    }
}
package com.javatpoint;

import com.javatpoint.jjk.Boy;
import com.javatpoint.jjk.Human;
import com.javatpoint.jjk.HumanManager;
import com.javatpoint.jjk.Man;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@SpringBootApplication
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class AopBeforeAdviceExampleApplication {
	public static void main(String[] args) {
		ApplicationContext context = new AnnotationConfigApplicationContext(HumanManager.class);

		Human human = context.getBean("human", Human.class);
		System.out.println("---------------------This is a Human.");
		human.say("hello!");
		human.jump();
		human.run();

		Human man = context.getBean("man", Man.class);
		System.out.println("---------------------This is a Man.");
		man.say("hello!");
		man.jump();
		man.run();

		Human boy = context.getBean("boy", Boy.class);
		System.out.println("---------------------This is a Boy.");
		boy.say("hello!");
		boy.jump();
		boy.run();
	}
}
---------------------This is a Human.
@within --- A1
@target --- A1
Human says:hello!
@within --- A1
@target --- A1
Human jump.
@within --- A1
@target --- A1
Human runs.
---------------------This is a Man.
@within --- A1
@target --- A2
Human says:hello!
@within --- A1
@target --- A2
Human jump.
@within --- A2
@target --- A2
Man runs.
---------------------This is a Boy.
@within --- A1
Human says:hello!
Boy jump.
@within --- A2
Man runs.

資料

  • https://blog.csdn.net/qq_36917119/article/details/108123440
  • https://blog.csdn.net/demon7552003/article/details/97601209
  • https://blog.csdn.net/yangshangwei/article/details/77846974