您的位置:首页 > 编程语言 > Java开发

spring注解和springmvc容器初始化过程

2016-09-27 14:55 302 查看
本节主要通过一个自定义注解了解注解是什么,然后简要介绍下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
或[code]@Resource
对类内部成员属性进行注解,相当于xml配置的property。使用时候根据情况,可以设置name值,比如@Component("boss"),因为初始化时默认类是singleton的,这个boss相当于[/code]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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: