學習Butterknife的一點心得(系列)一

咱們實現一個完整的一個例子,那麼基本瞭解了其運行機制。
java

1  建立一個處理註解的項目框架

    

依次爲一個註解,一個註解處理器,一個註解路徑配置文件(供編譯器識別)。ide

註解Seriable代碼:測試

@Target({ ElementType.FIELD, ElementType.TYPE })  
@Retention(RetentionPolicy.CLASS) 
public @interface Seriable {

}

@Retention標明生命週期,this

RetentionPolicy.CLASS //表示註解是在編譯期處理

這個配置文件的內容是BeanProcessor.java的完整路徑:com.zhy.annotationprocess.processor.BeanProcessor.spa

這個BeanProcessor.java的代碼爲:code

@SupportedSourceVersion(SourceVersion.RELEASE_6)
public class BeanProcessor extends AbstractProcessor { // 元素操做的輔助類
	Elements elementUtils;

	ProcessingEnvironment  processingEnv;
	
	@Override
	public synchronized void init(ProcessingEnvironment processingEnv) {
		super.init(processingEnv);
		// 元素操做的輔助類
		elementUtils = processingEnv.getElementUtils();
		this.processingEnv = processingEnv;
		
	}

	@Override
	public Set<String> getSupportedAnnotationTypes() {

		Set<String> typeSet = new LinkedHashSet<String>();

		typeSet.add(Seriable.class.getCanonicalName());

		return typeSet;
	}

	@SuppressWarnings("resource")
	@Override
	public boolean process(Set<? extends TypeElement> annotations,
			RoundEnvironment roundEnv) {
		
		processingEnv.getMessager().printMessage(Kind.ERROR, "12346789");
		
		// 得到被該註解聲明的元素
		Set<? extends Element> elememts = roundEnv
				.getElementsAnnotatedWith(Seriable.class);
		TypeElement classElement = null;// 聲明類元素
		List<VariableElement> fields = null;// 聲明一個存放成員變量的列表
		// 存放兩者
		Map<String, List<VariableElement>> maps = new HashMap<String, List<VariableElement>>();
		try {
			// 遍歷
			File file = new File("f:/test.txt");
			FileWriter fWriter = null;
			fWriter = new FileWriter(file,true);
			
			FileOutputStream outputStream = new FileOutputStream(file,true);
			outputStream.write((" ======elememts size : " +elememts.size()+ "\n").getBytes());
			int i = 1;
			for (Element ele : elememts) {
				//processingEnv.getMessager().printMessage(Kind.ERROR, "12346789",ele);
				outputStream.write((" ======start\n").getBytes());
				outputStream.write((" element name:" + ele.getSimpleName() + " index:" + i + "\n").getBytes());
				outputStream.write((" element enclose_name:"+ele.getEnclosingElement().getSimpleName()+"\n").getBytes());
				outputStream.write(( "element kind:" + ele.getKind().name() + "\n").getBytes());
				outputStream.write(( " element type:" + ele.asType().getKind().name() + "\n").getBytes());
				outputStream.write(("========end\n").getBytes());
				i++;
			}
			
			outputStream.flush();
			outputStream.close();
			
		} catch (IOException e) {
			e.printStackTrace();
		}

		return true;
	}

}

而後將其打成一個jar。three


2  建立一個測試簡單註解框架的項目生命週期

  

percent_1.jar就是剛纔打的jar包element


Article.java和User.java的代碼分別爲:

@Seriable  
public class Article  
{   
    private String title ;          
    private String content ;        
}   


public class User   
{  
    @Seriable
     int username123;            
    @Seriable  
     String password123;  
  
    private String three;   
    private String four;   
}

對AnntotaionTest1項目配置,使編譯器能識別jar中的註解處理器BeanProcessor。


配置完以後回頭看BeanProcessor,編譯器識別它以後,會調用它的process(...)入口,根據代碼會在F盤建立一個test.txt文件,裏面打印了被註解的元素的信息。如今咱們來看一下這個文件的內容:

 ======elememts size : 3

 ======start

 element name:username123 index:1

 element enclose_name:User

element kind:FIELD

 element type:INT

========end

 ======start

 element name:Article index:2

 element enclose_name:com

element kind:CLASS

 element type:DECLARED

========end

 ======start

 element name:password123 index:3

 element enclose_name:User

element kind:FIELD

 element type:DECLARED

========end

 ======elememts size : 0

果真打印出了3條註解元素的信息,這和咱們在User和Article註解的元素一一對應。

這裏解釋一下:element name的值意思爲註解元素的名稱,element enclose_name:是封裝這個元素的實體名稱,element kind的值被註解元素的角色,字段或者類等其餘,element type:的值表示被註解元素的類型,username123被定義成int,它的type就爲INT,password123被定義成String,它的type就爲DECLARED。至此簡單的編譯註解完成測試。在寫註解處理器的時候有一點要注意,就是必須實現getSupportedAnnotationTypes()方法

相關文章
相關標籤/搜索