1. 程式人生 > >Spring註解實現原理

Spring註解實現原理

先來說說註解是什麼:

註解顧名思義,就是類似於添加註釋,但是又不跟註釋完全一樣,因此,我們可以將它理解為將類或者方法與特定的資訊進行關聯。

那麼註解如何實現?

1、介面使用@interface定義。

2、通過繼承以下註解,實現功能:

 元註解@Target,@Retention,@Documented,@Inherited 

* 元註解@Target,@Retention,@Documented,@Inherited *  * @Target 表示該註解用於什麼地方,可能的 ElemenetType 引數包括:  * ElemenetType.CONSTRUCTOR 構造器宣告  * ElemenetType.FIELD 域宣告(包括 enum 例項)  * ElemenetType.LOCAL_VARIABLE 區域性變數宣告  * ElemenetType.METHOD 方法宣告  * ElemenetType.PACKAGE 包宣告  * ElemenetType.PARAMETER 引數宣告  * ElemenetType.TYPE 類,介面(包括註解型別)或enum宣告  *  * @Retention 表示在什麼級別儲存該註解資訊。可選的 RetentionPolicy 引數包括:  * RetentionPolicy.SOURCE 註解將被編譯器丟棄  * RetentionPolicy.CLASS 註解在class檔案中可用,但會被VM丟棄  * RetentionPolicy.RUNTIME VM將在執行期也保留註釋,因此可以通過反射機制讀取註解的資訊。  *  * @Documented 將此註解包含在 javadoc 中  *  * @Inherited 允許子類繼承父類中的註解

@Target(ElementType.METHOD)  @Retention(RetentionPolicy.RUNTIME)  @Documented  @Inherited 

 下面拿spring的controller來當做示例:

         Controller類使用繼承@Component註解的方法,將其以單例的形式放入spring容器,如果仔細看的話會發現每個註解裡面都有一個預設的value()方法,它的作用是為當前的註解宣告一個名字,一般預設為類名,然後spring會通過配置檔案中的<context:component-scan>的配置,進行如下操作:

1、使用asm技術掃描.class檔案,並將包含@Component及元註解為@Component的註解@Controller、@Service、@Repository或者其他自定義的的bean註冊到beanFactory中,

2、然後spring在註冊處理器

3、例項化處理器,然後將其放到beanPostFactory中,然後我們就可以在類中進行使用了。

4、建立bean時,會自動呼叫相應的處理器進行處理。

@Controller原始碼:

/*
 * Copyright 2002-2007 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.stereotype; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Indicates that an annotated class is a "Controller" (e.g. a web controller). * * <p>This annotation serves as a specialization of {@link Component @Component}, * allowing for implementation classes to be autodetected through classpath scanning. * It is typically used in combination with annotated handler methods based on the * {@link org.springframework.web.bind.annotation.RequestMapping} annotation. * * @author Arjen Poutsma * @author Juergen Hoeller * @since 2.5 * @see Component * @see org.springframework.web.bind.annotation.RequestMapping * @see org.springframework.context.annotation.ClassPathBeanDefinitionScanner */ @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Controller { /** * The value may indicate a suggestion for a logical component name, * to be turned into a Spring bean in case of an autodetected component. * @return the suggested component name, if any */ String value() default ""; }

下面是@Component的原始碼:

/*
 * Copyright 2002-2007 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.stereotype;

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

/**
 * Indicates that an annotated class is a "component".
 * Such classes are considered as candidates for auto-detection
 * when using annotation-based configuration and classpath scanning.
 *
 * <p>Other class-level annotations may be considered as identifying
 * a component as well, typically a special kind of component:
 * e.g. the {@link Repository @Repository} annotation or AspectJ's
 * {@link org.aspectj.lang.annotation.Aspect @Aspect} annotation.
 *
 * @author Mark Fisher
 * @since 2.5
 * @see Repository
 * @see Service
 * @see Controller
 * @see org.springframework.context.annotation.ClassPathBeanDefinitionScanner
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Component {

	/**
	 * The value may indicate a suggestion for a logical component name,
	 * to be turned into a Spring bean in case of an autodetected component.
	 * @return the suggested component name, if any
	 */
	String value() default "";

}