【Spring依赖注入】

Annotation(注解)

注解本质上是Java推出的一种特殊的可在编译、运行阶段读取的注释。

package org.springframework.stereotype;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";
}
1. Target

本身也是一个注解,只有一个数组属性,用于设定该注解的目标范围,可同时设定多个范围。

// 用于类、接口类、枚举类
ElementType.TYPE
// 用于类的属性
ElementType.FLELD
// 用与类的方法上
ElementType.METHOD
// 用于类的参数上
ElementType.PARAMETER
// 例子
@Target({ElementType.TYPE,ElementType.METHOD})
2. Retention

即声明该注解的生命周期,三个值可选SOURCE(纯注释)、CLASS(编译阶段)、RUNTIME(运行时)

@Retention(RetentionPolicy.RUNTIME)
3. Documented

其作用就是将注释的元素包含到JavaDoc文档中,一般情况下,都会添加这个注解

4. @interface

即声明当前的Java类型为Annotation,固定语法

5. Annotation属性

类似类的属性,约定该属性的类型和属性名称,默认属性名称是value可省略

String value() default "";
6. 举个栗子
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {

	// 即别名的意思,通过别名也可以访问该属性
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";
    
    boolean required() default true;

    String defaultValue() default ValueConstants.DEFAULT_NONE;
}

Spring Bean

IoC(Inversion of Control,控制反转)容器是Spring框架最核心的组件,
主要通过依赖注入(Dependecy Injection,DI)实现IoC,所有的Java对象都会通过该容器转变为Bean(Spring对象的一种称呼)。
在这里插入图片描述

// 运行下面的代码启动IoC容器
ApplicationContext context = 
    new AnnotationConfigApplicationContext("com.kevin.spring");
// 不再需要实例化接口的实现类,而是直接使用接口(面向接口编程)
FileService fileService = context.getBean(FileService.class);

这段代码的含义就是启动IoC容器,并且会加载包com.kevin.spring下的Bean(只要引用了Spring注解的类都可以被加载)

// Spring官方声明为Spring Bean的注解有:
1. 通用的Bean注解,其余三个是器扩展
org.springframework.stereotype.Component
org.springframework.stereotype.Service
2. 作用于Web Bean,一般情况下使用@Service,如果是Web则用@Controller
org.springframework.stereotype.Controller
org.springframework.stereotype.Repository

加注解的作用,是让 Spring 系统 自动 管理 各种实例。
所谓 管理,就是用 @Service 注解把 SubjectServiceImpl和 SongServiceImpl等等所有服务实现,都标记成 Spring Bean;然后,在任何需要使用服务的地方,用@Autowired 注解标记,告诉 Spring 这里需要注入实现类的实例。

项目启动过程中,Spring 会 自动 实例化服务实现类,然后自动注入到变量中,不需要开发者大量的写new代码了,就解决了上述的开发者需要大量写代码而导致容易出错的问题,

@Service 和 @Autowired 是相辅相成的:如果 SongServicelmp没有加 @Service ,就意味着没有标记成 Spring Bean,那么即使加了 @Autowired 也无法注入实例;而
private SongService songService; 属性忘记加 @Autowired Spring Bean 亦无法注入实例。二者缺一不可。

每个 Annotation(注解)都有各自特定的功能,Spring 检查到代码中有注解,就自动完成特定功能,减少代码量、降低系统复杂度。
初学 Spring,需要理解 并牢记 常见的这些注解的功能和作用。

Spring Resource

Maven执行package的时候,会把resource目录下的文件一起打包进jar包里,jar文件是从包路径开始的,Maven工程编译后会自动去掉src/main/javasrc/main/resources目录(一般我们的数据文件都会放在resources目录下)

classpath

在Java内部我们一般将文件路径称为classpath,其指定的文件不能解构成File对象化,但是可以解析成InputStream,借助JavaIO就可以取出来了

public class Test {
  public static void main(String[] args) {
    // 读取 classpath 的内容
    // 从Java运行的类加载器(ClassLoader)实例中查找文件
    // Test.class指的是当前Test.java文件编译后的Java Class文件
    InputStream in = 
    	Test.class.getClassLoader().getResourceAsStream("data.json");
    // 使用 commons-io 库读取文本
    try {
      String content = IOUtils.toString(in, "utf-8");
      System.out.println(content);
    } catch (IOException e) {
      // IOUtils.toString 有可能会抛出异常,需要我们捕获一下
      e.printStackTrace();
    }
  }
}
ResourceLoader

在Spring中定义了一个org.springframework.core.io.Resource类来封装文件,这个类的优势在于既可以封装普通的File也可以支持classpath文件,甚至是远程文件。并且在Spring中通过org.springframework.core.io.ResourceLoader可以在任意的Spring Bean中引入ResourceLoader,举个读取resource文件夹下的json文件

package com.kevin.spring.service.impl;

import ...

@Service
public class SongListServiceImpl implements SongListService {

    private static Map<String,SongList> songListMap = new HashMap<>();

    @Autowired
    private ResourceLoader loader;

    @PostConstruct
    public void init() {
        try {
            InputStream in = 
         		loader.getResource("classpath:data/songlists.json").getInputStream();
            String jsonString = IOUtils.toString(in, "utf-8");
            SongList[] lists = JSON.parseObject(jsonString, SongList[].class);
            for(SongList songList : lists){
                songListMap.put(songList.getId(),songList);
            }
        } catch (IOException e) {
            e.fillInStackTrace();
        }
    }

    @Override
    public SongList get(String songListId) {
        return songListMap.get(songListId);
    }
}

Spring Bean 的生命周期

在这里插入图片描述
大部分时候我们只需要掌握init方法,其方法名是任意的,因为我们是通过注解来声明该方法的

import javax.annotation.PostConstruct;

@Service
public class SubjectServiceImpl implements SubjectService {

  // 这个注解意思是该方法在Spring Bean启动后自动执行
  // 因此可以将一些初始化的代码放入其中,例如static代码块
  @PostConstruct
  public void init(){
      System.out.println("启动啦");
      Subject subject = new Subject();
      subject.setId("s001");
      subject.setName("成都");
      subject.setMusician("赵雷");
      subjectMap.put(subject.getId(), subject);
  }

} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帕特里克_海星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值