Spring(IOC/AOP)注解学习

1.1. spring的初始化顺序

在spring的配置文件中配置bean,如下

Spring(IOC/AOP)注解学习

在One类和Two类中,分别实现一个参数的构造如下

Spring(IOC/AOP)注解学习

Spring(IOC/AOP)注解学习

加载spring配置文件,初始化bean如下

Spring(IOC/AOP)注解学习

那么。结果如何呢?

Spring(IOC/AOP)注解学习

结论:spring会按照bean的顺序依次初始化xml中配置的所有bean

1.1.1.   通过ApplicationContextAware加载Spring上下文环境

在One中实现ApplicationContextAware接口会出现如何的变换呢?

Spring(IOC/AOP)注解学习

结果

Spring(IOC/AOP)注解学习

1.1.2.   InitializingBean的作用

在One中实现InitializingBean接口呢?

Spring(IOC/AOP)注解学习

结果:

Spring(IOC/AOP)注解学习

1.1.3.  如果使用注解@Component

使用@Component注入类,那么它的顺序是如何呢?

1.1.4.   结论

1、  spring先检查注解注入的bean,并将它们实例化

2、  然后spring初始化bean的顺序是按照xml中配置的顺序依次执行构造

3、  如果某个类实现了ApplicationContextAware接口,会在类初始化完成后调用setApplicationContext()方法进行操作

4、  如果某个类实现了InitializingBean接口,会在类初始化完成后,并在setApplicationContext()方法执行完毕后,调用afterPropertiesSet()方法进行操作

1.2. 注解使用回顾

         1、在spring中,用注解来向Spring容器注册Bean。需要在applicationContext.xml中注册<context:component-scan base-package=”pagkage1[,pagkage2,…,pagkageN]”/>。

         2、如果某个类的头上带有特定的注解@Component/@Repository/@Service/@Controller,就会将这个对象作为Bean注册进Spring容器

         3、在使用spring管理的bean时,无需在对调用的对象进行new的过程,只需使用@Autowired将需要的bean注入本类即可

1.3. 自定义注解

1.3.1.   解释

1、自定义注解的作用:在反射中获取注解,以取得注解修饰的“类、方法、属性”的相关解释。

2、java内置注解

     @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   JVM将在运行期也保留注释,因此可以通过反射机制读取注解的信息。

1.3.2.   实现

定义自定义注解

@Target({ ElementType.TYPE })//注解用在接口上

@Retention(RetentionPolicy.RUNTIME)//VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息,生命周期

@Component

public @interface RpcService {

         String value();

}

2、将直接类加到需要使用的类上,我们可以通过获取注解,来得到这个类

@RpcService("HelloService")

public class HelloServiceImpl implements HelloService {

    public String hello(String name) {

        return "Hello! " + name;

    }

}

3、类实现的接口

public interface HelloService {

    String hello(String name);

}

4、通过ApplicationContext获取所有标记这个注解的类

//ApplicationContextAware会为Component组件调用setApplicationContext方法;

@Component

public class MyServer implements ApplicationContextAware {

         @SuppressWarnings("resource")

         public static void main(String[] args) {

       new ClassPathXmlApplicationContext("spring2.xml");

    }

         public void setApplicationContext(ApplicationContext ctx)

                           throws BeansException {

                  Map<String, Object> serviceBeanMap = ctx

                                    .getBeansWithAnnotation(RpcService.class);

                  for (Object serviceBean : serviceBeanMap.values()) {

                           try {

                                    //获取自定义注解上的value:    HelloService
    String value = serviceBean.getClass().getAnnotation(RpcService.class).value();
    System.out.println("注解上的value: " + value);

    //反射被注解类,并调用指定方法

                                    Method method = serviceBean.getClass().getMethod("hello", new Class[]{String.class});

                                    Object invoke = method.invoke(serviceBean, "bbb");

                                    System.out.println(invoke);

                           } catch (Exception e) {

                                    e.printStackTrace();

                           }

                  }

         }

}

5、  结合spring实现junit测试

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = "classpath:spring2.xml")

public class MyServer implements ApplicationContextAware {

         @Test

         public void helloTest1() {

 

         }

 

         public void setApplicationContext(ApplicationContext ctx)

                           throws BeansException {

                  Map<String, Object> serviceBeanMap = ctx

                                    .getBeansWithAnnotation(RpcService.class);

                  for (Object serviceBean : serviceBeanMap.values()) {

                           try {

                                    Method method = serviceBean.getClass().getMethod("hello",

                                                      new Class[] { String.class });

                                    Object invoke = method.invoke(serviceBean, "bbb");

                                    System.out.println(invoke);

                           } catch (Exception e) {

                                    e.printStackTrace();

                           }

                  }

         }

 

}