一、自定义注解

   @Interface自动继承了java.lang.annotation.Annotation接口进行自定义注解,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。

  定义注解格式:
  public @interface 注解名 {定义体}

  @Target:

  表示该注解可以用于什么地方,可能的ElementType参数有:
  CONSTRUCTOR:构造器的声明
  FIELD:域声明(包括enum实例)
  LOCAL_VARIABLE:局部变量声明
  METHOD:方法声明
  PACKAGE:包声明
  PARAMETER:参数声明
  TYPE:类、接口(包括注解类型)或enum声明

  @Retention:

  表示需要在什么级别保存该注解信息。可选的RetentionPolicy参数包括:
  SOURCE:注解将被编译器丢弃
  CLASS:注解在class文件中可用,但会被VM丢弃
  RUNTIME:VM将在运行期间保留注解,因此可以通过反射机制读取注解的信息

  @Document:

  将注解包含在Javadoc中

  @Inherited:

  允许子类继承父类中的注解

  实例

  自定义注解范围为类

package zidingyi;

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 Table {

	String value() default "";
}

  自定义注解范围为域

package zidingyi;

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


import jdk.internal.instrumentation.TypeMapping;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)

public @interface Colum {
	String value() default "";
}

  使用自定义注解

  

package zidingyi;
@Table("user")
public class User {

	@Colum("_id")
	private String id;
	
	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Colum("name")
	private String name;
}

二、使用@AspectJ

  1、Aspect简单使用

    创建目标类  

package aspectj;

public class WaiterNew {

	public void greetTo(String clientName){
		System.out.println("greet To:"+clientName);
	}
	public void serverTo(String clientName){
		System.out.println("serverTo:"+clientName);
	}
}

    创建切面类

package aspectj;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

//通过@Aspectj注解将该类标示为切面
@Aspect
public class GreetToAspect {
//定义增强和切点
	@Before("execution(* aspectj.WaiterNew.greetTo(..))")
	public void beforeGreeting(){//该部分为增强的逻辑
		System.out.println("How Are You");
	}
}

  测试

package aspectj;

import org.aspectj.lang.annotation.Aspect;
import org.springframework.aop.aspectj.AspectInstanceFactory;
import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;


public class AspectJTest {

	public static void main(String[] args){
		WaiterNew waiterNew = new WaiterNew();
		AspectJProxyFactory factory = new AspectJProxyFactory();
		factory.setTarget(waiterNew);
		factory.addAspect(GreetToAspect.class);
		WaiterNew waiterNew2 = factory.getProxy();
		waiterNew2.greetTo("abc");
		waiterNew2.serverTo("bcd");
	}
}

  切点语法

    @Aspect是一种定义切面的注解。

    @Before是一种前置增强的注解,相当于MethodBeforeAdvice类。

    @AfterReturning是一种后置增强的注解,相当于AfterReturningAdvice类。

    @Around是一种环绕增强注解,相当于MethodInterceptor类。

    @AfterThrowing是一种异常抛出增强注解,相当于ThrowsAdvice类。

    复合切点

    复合切点是多个节点的组合,复合切点通过逻辑运算符进行组合,逻辑运算符如下:

    &&:表示多个切点的交集。

    ||:表示多个切点的并集。

    !:相当于切点的反集运算。

  切点函数

     方法切点函数

     通过描述目标类方法定义连接点

      execution():表示匹配所有该目标类方法的连接点

      @annotation:表示标注了特定注解的目标类方法作为连接点。

     方法入参函数

      args():表示目标类方法入参时的对象类型指定连接点。

      @args():表示入参对象是否标注指定注解指定连接点。

     目标类切点函数

      target():与指定类名相符的目标类中的所有函数作为连接点。

      @target():将标注指定注解的类中的所有函数作为连接点。

      within():与指定类名相符的目标类中的所有函数作为连接点。

      @within():将标注指定注解的类中的所有函数作为连接点。