Spring(IOC/AOP)注解学习

客官°小女子只卖身不卖艺 2022-05-22 10:15 360阅读 0赞

Spring的初始化顺序

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

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
  3. <bean id="one" class="cn.itcast_04_springannotation.springrunorder.One">
  4. <constructor-arg name="one" value="one"/>
  5. </bean>
  6. <bean id="two" class="cn.itcast_04_springannotation.springrunorder.Two">
  7. <constructor-arg name="two" value="two" />
  8. </bean>
  9. </beans>

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

  1. package cn.itcast_04_springannotation.springrunorder;
  2. public class One{
  3. public One(String one) {
  4. System.out.println(one);
  5. }
  6. }
  7. package cn.itcast_04_springannotation.springrunorder;
  8. public class Two {
  9. public Two(String two) {
  10. System.out.println(two);
  11. }
  12. }

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

  1. package cn.itcast_04_springannotation.springrunorder;
  2. import org.springframework.context.support.ClassPathXmlApplicationContext;
  3. public class Start {
  4. public static void main(String[] args) {
  5. new ClassPathXmlApplicationContext("spring.xml");
  6. }
  7. }

这里写图片描述

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

通过ApplicationContextAware加载Spring上下文环境

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

  1. package cn.itcast_04_springannotation.springrunorder;
  2. import org.springframework.beans.BeansException;
  3. import org.springframework.beans.factory.InitializingBean;
  4. import org.springframework.context.ApplicationContext;
  5. import org.springframework.context.ApplicationContextAware;
  6. public class One implements ApplicationContextAware {
  7. public One(String one) {
  8. System.out.println(one);
  9. }
  10. @Override
  11. public void setApplicationContext(ApplicationContext arg0)
  12. throws BeansException {
  13. System.out.println("setApplicationContext");
  14. }
  15. }

这里写图片描述

InitializingBean的作用

在One中实现InitializingBean接口呢?

  1. package cn.itcast_04_springannotation.springrunorder;
  2. import org.springframework.beans.BeansException;
  3. import org.springframework.beans.factory.InitializingBean;
  4. import org.springframework.context.ApplicationContext;
  5. import org.springframework.context.ApplicationContextAware;
  6. public class One implements ApplicationContextAware ,InitializingBean {
  7. public One(String one) {
  8. System.out.println(one);
  9. }
  10. @Override
  11. public void setApplicationContext(ApplicationContext arg0)
  12. throws BeansException {
  13. System.out.println("setApplicationContext");
  14. }
  15. @Override
  16. public void afterPropertiesSet() throws Exception {
  17. System.out.println("afterPropertiesSet");
  18. }
  19. }

这里写图片描述

如果使用注解@Component

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

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
  3. <bean id="one" class="cn.itcast_04_springannotation.springrunorder.One">
  4. <constructor-arg name="one" value="one"/>
  5. </bean>
  6. <context:component-scan base-package="cn.itcast_04_springannotation.springrunorder"/>
  7. <bean id="two" class="cn.itcast_04_springannotation.springrunorder.Two">
  8. <constructor-arg name="two" value="two" />
  9. </bean>
  10. </beans>
  11. package cn.itcast_04_springannotation.springrunorder;
  12. import org.springframework.stereotype.Component;
  13. @Component
  14. public class Three {
  15. public Three() {
  16. System.out.println("three");
  17. }
  18. public Three(String three) {
  19. System.out.println(three);
  20. }
  21. }

这里写图片描述

结论

1、 spring先检查注解注入的bean,并将它们实例化
2、 然后spring初始化bean的顺序是按照xml中配置的顺序依次执行构造
3、 如果某个类实现了ApplicationContextAware接口,会在类初始化完成后调用setApplicationContext()方法进行操作
4、 如果某个类实现了InitializingBean接口,会在类初始化完成后,并在setApplicationContext()方法执行完毕后,调用afterPropertiesSet()方法进行操作

注解使用回顾

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、自定义注解的作用:在反射中获取注解,以取得注解修饰的“类、方法、属性”的相关解释。
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.定义自定义注解

  1. package cn.itcast_04_springannotation.userdefinedannotation.annotation;
  2. import java.lang.annotation.ElementType;
  3. import java.lang.annotation.Retention;
  4. import java.lang.annotation.RetentionPolicy;
  5. import java.lang.annotation.Target;
  6. import org.springframework.stereotype.Component;
  7. @Target({ ElementType.TYPE })//注解用在接口上
  8. @Retention(RetentionPolicy.RUNTIME)//VM将在运行期也保留注释,因此可以通过反射机制读取注解的信息
  9. @Component
  10. public @interface RpcService {
  11. String value();
  12. }

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

  1. package cn.itcast_04_springannotation.userdefinedannotation.service.impl;
  2. import cn.itcast_04_springannotation.userdefinedannotation.annotation.RpcService;
  3. import cn.itcast_04_springannotation.userdefinedannotation.service.HelloService;
  4. @RpcService("HelloServicebb")
  5. public class HelloServiceImpl implements HelloService {
  6. public String hello(String name) {
  7. return "Hello! " + name;
  8. }
  9. public void test(){
  10. System.out.println("test");
  11. }
  12. }

3、类实现的接口

  1. package cn.itcast_04_springannotation.userdefinedannotation.service;
  2. public interface HelloService {
  3. String hello(String name);
  4. }

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

  1. package cn.itcast_04_springannotation.userdefinedannotation.test;
  2. import java.lang.reflect.Method;
  3. import java.util.Map;
  4. import org.springframework.beans.BeansException;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.context.ApplicationContext;
  7. import org.springframework.context.ApplicationContextAware;
  8. import org.springframework.context.support.ClassPathXmlApplicationContext;
  9. import org.springframework.stereotype.Component;
  10. import cn.itcast_04_springannotation.userdefinedannotation.annotation.RpcService;
  11. import cn.itcast_04_springannotation.userdefinedannotation.service.HelloService;
  12. @Component //ApplicationContextAware会为Component组件调用setApplicationContext方法;
  13. public class MyServer implements ApplicationContextAware {
  14. @SuppressWarnings("resource")
  15. public static void main(String[] args) {
  16. ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring2.xml");
  17. }
  18. public void setApplicationContext(ApplicationContext ctx)
  19. throws BeansException {
  20. Map<String, Object> serviceBeanMap = ctx
  21. .getBeansWithAnnotation(RpcService.class);
  22. for (Object serviceBean : serviceBeanMap.values()) {
  23. try {
  24. //获取自定义注解上的value
  25. String value = serviceBean.getClass().getAnnotation(RpcService.class).value();
  26. System.out.println("注解上的value: " + value);
  27. //反射被注解类,并调用指定方法
  28. Method method = serviceBean.getClass().getMethod("hello",
  29. new Class[] { String.class });
  30. Object invoke = method.invoke(serviceBean, "bbb");
  31. System.out.println(invoke);
  32. } catch (Exception e) {
  33. e.printStackTrace();
  34. }
  35. }
  36. }
  37. }

这里写图片描述

  1. package cn.itcast_04_springannotation.userdefinedannotation.test;
  2. import java.lang.reflect.Method;
  3. import java.util.Map;
  4. import org.springframework.beans.BeansException;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.context.ApplicationContext;
  7. import org.springframework.context.ApplicationContextAware;
  8. import org.springframework.context.support.ClassPathXmlApplicationContext;
  9. import org.springframework.stereotype.Component;
  10. import cn.itcast_04_springannotation.userdefinedannotation.annotation.RpcService;
  11. import cn.itcast_04_springannotation.userdefinedannotation.service.HelloService;
  12. public class MyServer2 implements ApplicationContextAware {
  13. @SuppressWarnings("resource")
  14. public static void main(String[] args) {
  15. ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("spring2.xml");
  16. Map<String, Object> beans = ctx.getBeansWithAnnotation(RpcService.class);
  17. for(Object obj: beans.values()){
  18. HelloService hello=(HelloService) obj;
  19. String hello2 = hello.hello("mmmm");
  20. System.out.println(hello2);
  21. }
  22. }
  23. public void setApplicationContext(ApplicationContext ctx)
  24. throws BeansException {
  25. Map<String, Object> serviceBeanMap = ctx
  26. .getBeansWithAnnotation(RpcService.class);
  27. for (Object serviceBean : serviceBeanMap.values()) {
  28. try {
  29. Method method = serviceBean.getClass().getMethod("hello",
  30. new Class[] { String.class });
  31. Object invoke = method.invoke(serviceBean, "bbb");
  32. System.out.println(invoke);
  33. } catch (Exception e) {
  34. e.printStackTrace();
  35. }
  36. }
  37. }
  38. }

这里写图片描述

5、 结合spring实现junit测试

  1. package cn.itcast_04_springannotation.userdefinedannotation.test;
  2. import org.junit.Test;
  3. import org.junit.runner.RunWith;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.stereotype.Component;
  6. import org.springframework.test.context.ContextConfiguration;
  7. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  8. import cn.itcast_04_springannotation.userdefinedannotation.service.HelloService;
  9. @RunWith(SpringJUnit4ClassRunner.class)
  10. @ContextConfiguration(locations = "classpath:spring2.xml")
  11. @Component
  12. public class MyServer3 {
  13. @Autowired
  14. HelloService helloService;
  15. @Test
  16. public void helloTest1() {
  17. System.out.println("开始junit测试……");
  18. String hello = helloService.hello("ooooooo");
  19. System.out.println(hello);
  20. }
  21. }

这里写图片描述

发表评论

表情:
评论列表 (有 0 条评论,360人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java注解学习

    元注解 首先Java提供了4个元注解来定义其他注解 @Target用来定义注解将应用于什么地方(如一个方法或者一个域) @Retention用来定义注解在哪一个

    相关 注解学习

    > 注解是java1.5引入的,比如@Override,@Deprecated等都是比较常见的注解,Java程序员在日常开发中注解使用广泛. 一.什么是注解 下面简单看