Spring(IOC/AOP)注解学习
1.1. spring的初始化顺序
在spring的配置文件中配置bean,如下
在One类和Two类中,分别实现一个参数的构造如下
加载spring配置文件,初始化bean如下
那么。结果如何呢?
结论:spring会按照bean的顺序依次初始化xml中配置的所有bean
1.1.1. 通过ApplicationContextAware加载Spring上下文环境
在One中实现ApplicationContextAware接口会出现如何的变换呢?
结果
1.1.2. InitializingBean的作用
在One中实现InitializingBean接口呢?
结果:
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 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(); } } }
} |