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 "";
}