spring註解和springmvc容器初始化過程

本節主要通過一個自定義註解瞭解註解是什麼,然後簡要介紹下spring註解分類和作用,最後簡要概括一下web spring容器初始化過程;

1、自定義Annotation_my註解

@Target({ElementType.METHOD,ElementType.TYPE})
@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Annotation_my {

    String name() default "張三";//defalt 表示默認值
    
    String say() default "hello world";
    
    int age() default 21;
}

上面是按照定義規範自定義一個註解接口,@Annotation_my,你也可以把註解理解爲一個接口,其實他就是一個註釋作用;然後定義person接口

public interface Person {

    public void name();

    public void say();
    

    public void age();
}

實現接口(student)

@Annotation_my
@SuppressWarnings("unused")
public class Student implements Person {

       private String name;

        @Override
        @Annotation_my(name="流氓公子") //賦值給name  默認的爲張三
    //在定義註解時沒有給定默認值時,在此處必須name賦初值
        public void name() {
            
        }


        @Override
        @Annotation_my(say=" hello world  !")
        public void say() {
            
        }

        @Override
        @Annotation_my(age=20)
        public void age() {
            
        }
}

這裏使用了上面自定義註解,在類外部使用,相當於@Component,然後方法上面定義的註解,相當於方法的註解;最後我們來使用test類測試一下效果,如下:

public class Test {

    Annotation[] annotation = null;

    public static void main(String[] args) throws ClassNotFoundException {
        new Test().getAnnotation();
    }
    public void getAnnotation() throws ClassNotFoundException{
        Class<?> stu = Class.forName("com.qzx.web.anotation.Student");//靜態加載類
        boolean isEmpty = stu.isAnnotationPresent(com.qzx.web.anotation.Annotation_my.class);//判斷stu是不是使用了我們剛纔定義的註解接口
        if(isEmpty){
            annotation = stu.getAnnotations();//獲取註解接口中的
            for(Annotation a:annotation){
                Annotation_my my = (Annotation_my)a;//強制轉換成Annotation_my類型
                System.out.println(stu+":\n"+my.name()+" say: "+my.say()+" my age: "+my.age());
            }
        }
        Method[] method = stu.getMethods();//
        System.out.println("Method");
        for(Method m:method){
            boolean ismEmpty = m.isAnnotationPresent(com.qzx.web.anotation.Annotation_my.class);
            if(ismEmpty){
                Annotation[] aa = m.getAnnotations();
                for(Annotation a:aa){
                    Annotation_my an = (Annotation_my)a;
                    System.out.println(m+":\n"+an.name()+" say: "+an.say()+" my age: "+an.age());
                }
            }
        }
        //get Fields by force
        System.out.println("get Fileds by force !");
        Field[] field = stu.getDeclaredFields();
        for(Field f:field){
            f.setAccessible(true);
            System.out.println(f.getName());
        }
        System.out.println("get methods in interfaces !");
        Class<?> interfaces[] = stu.getInterfaces();
        for(Class<?> c:interfaces){
            Method[] imethod = c.getMethods();
            for(Method m:imethod){
                System.out.println(m.getName());
            }
        }
        
    }
    
}

通過測試可以知道,註解其實就是註釋的作用,annotation = stu.getAnnotations();通過註釋(綁定到類或方法上),可以給當前對象定義一系列初始操作,比如定義類名稱,其他屬性等;這樣定義好後,spring容器掃描類時候,就能通過註解找到不同定義類型的類,然後進行初始化對象等操作。

2、下面介紹一下spring經常使用的註解

通用類註解 @component,業務層註解@Service,數據訪問層@Reposity ,controller控制器層@Controller,事務@Transaction,相當於xml配置時候的class;@Autowired@Resource對類內部成員屬性進行註解,相當於xml配置的property。使用時候根據情況,可以設置name值,比如@Component("boss"),因爲初始化時默認類是singleton的,這個boss相當於xml配置的id名稱,也就是對象id,到時候對象工廠可以通過BeanFactory bf = (BeanFactory) reg;
Object o = bf.getBean("boss")來找到對象。

3、springmvc初始化過程

tomcat容器爲例,當啓動web服務時候,初始化spring容器,web.xml中兩個地方配置;一個是監聽,一個是dispatcher,如下:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:beans.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

和 <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

web加載配置文件,首先初始化spring監聽服務,讀取beans.xml配置文件,該文件一般配置有數據源、SqlSessionFactory、事務和bean等,按照順序加載,當讀取到 <context:component-scan base-package ="com" />配置時候,打開spring掃描操作,容器會讀取com目錄及子目錄,掃描含有@註解標誌的class文件,掃描是按照類目遞歸進行:比如,掃描com.controller目錄的一個userAction類時,上面含有@Controller註解,beanfactory裝配該類實例(初始化就是生成beanDefinition的實例,BeanDefinition實例是用來描述Bean結構,一般還沒有實例化bean)將beanDefinition實例放入Bean工廠,接着掃描類文件中含有@註解的屬性,比如@AutoWire或@Resource的屬性,一般是service,裝配該類,放入工廠;如此反覆進行,裝配所有類文件。具體過程可以參考https://my.oschina.net/HeliosFly/blog/203149這篇文章。

至於DispatcherServlet這個配置,就是映射控制器中的方法、url路徑信息等,比如@RequestMapping("/index.do"),裝配userAction--methodName--url(index.do)。這樣映射後,當訪問http方法時候,就能找到路徑,然後就可以調用方法了。這些只是我大致理解,裏面有些知識點也不是很清晰,可以自己去查看相關資料,推薦https://my.oschina.net/HeliosFly/blog/203149

發佈了23 篇原創文章 · 獲贊 8 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章