Spring--@within和@target的区别

关于Spring中@within和@target注解的区别,很多书籍中,把这2个注解的作用翻译成一样的了,或者是总结的不清晰。官方文档中原文为:

Any join point (method execution only in Spring AOP) where the target object has a @Transactional annotation:

@target(org.springframework.transaction.annotation.Transactional)

Any join point (method execution only in Spring AOP) where the declared type of the target object has an @Transactional annotation:

@within(org.springframework.transaction.annotation.Transactional)

重点是declared type,因此写了以下示例:

示例

注解:

@Retention(RetentionPolicy.RUNTIME)
@Target( ElementType.TYPE)
public @interface A1 {

}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface A2 {

}

测试类型:

package demon.study.spring5.spring_aop.sample;

@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 demon.study.spring5.spring_aop.sample;

@A2
public class Man  extends Human{

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

	
}
package demon.study.spring5.spring_aop.sample;

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

}
package demon.study.spring5.spring_aop.sample;

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
@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();
	}
}

Aspect:

package demon.study.spring5.spring_aop.sample;

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


@Aspect
@Component
public class HumanAspect {

    @Before("@within(demon.study.spring5.spring_aop.sample.A1)")
    public void execute1(){
        System.out.println("@within(demon.study.spring5.spring_aop.sample.A1)");
    }

    @Before("@target(demon.study.spring5.spring_aop.sample.A1)")
    public void execute2(){
        System.out.println("@target(demon.study.spring5.spring_aop.sample.A1)");
    }
    
    @Before("@within(demon.study.spring5.spring_aop.sample.A2)")
    public void execute3(){
        System.out.println("@within(demon.study.spring5.spring_aop.sample.A2)");
    }

    @Before("@target(demon.study.spring5.spring_aop.sample.A2)")
    public void execute4(){
        System.out.println("@target(demon.study.spring5.spring_aop.sample.A2)");
    }

    
}

测试入口:

package demon.study.spring5.spring_aop.sample;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;

 
public class Checker {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		test1();
	}
	
	
	public static void test1()
	{
		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(demon.study.spring5.spring_aop.sample.A1)
@target(demon.study.spring5.spring_aop.sample.A1)
Human says:hello!
@within(demon.study.spring5.spring_aop.sample.A1)
@target(demon.study.spring5.spring_aop.sample.A1)
Human jump.
@within(demon.study.spring5.spring_aop.sample.A1)
@target(demon.study.spring5.spring_aop.sample.A1)
Human runs.
---------------------This is a Man.
@within(demon.study.spring5.spring_aop.sample.A1)
@target(demon.study.spring5.spring_aop.sample.A2)
Human says:hello!
@within(demon.study.spring5.spring_aop.sample.A1)                         #没有对应的target
@target(demon.study.spring5.spring_aop.sample.A2)
Human jump.
@within(demon.study.spring5.spring_aop.sample.A2)        #A1注解未拦截不存在,因为runs方法属于Man类型,A1应用于Human。
@target(demon.study.spring5.spring_aop.sample.A2)        #A1注解未拦截不存在,因为runs方法属于Man类型,A1应用于Human。
Man runs.
---------------------This is a Boy.
@within(demon.study.spring5.spring_aop.sample.A1)                         #没有对应的target
Human says:hello!
Boy jump.
@within(demon.study.spring5.spring_aop.sample.A2)                         #没有对应的target
Man runs.

总结:

相同点:

对象的运行时绑定的方法所属的类必须与被@within或@target中的注解类型所注解的类是同一个类,方法拦截才生效

运行时绑定的方法是指运行时对象动态绑定的方法,一般指override方法。

@within,@target中的注解类型,本示例中指A1,A2

被A1注解的类有Human

被A2注解的类有Man。

 

不同点:

  • @target要求对象的运行时类型与被注解的类型是同一个类型
  • @within要求对象的运行时类型是被注解的类型的子类

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值