Spring依赖注入

1. 注解(Annotation)

Annotation 是可以在编译、运行阶段读取的
借助 Annotation 来实现一些功能增强,和 Python 的装饰器有类似之处

//这个代码很平常,但是多了一个 @Service
//这个注解的作用是声明引用该注解的Java类为Service对象
@Service
public class MessageServiceImpl implements MessageService{
    public String getMessage() {
         return "Hello World!";
    }
}

Annotation 也是一个 Java 类,只是有点特别。看看 Service 这个Annotation 的源代码

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.1 Target

java.lang.annotation.Target,自身也是一个注解,只有一个数组属性,用于设定该注解的目标范围,,比如说可以作用于类或方法等,因为是数组,所以可以同时设定多个范围,具体的作用类型配置在 java.lang.annotation.ElementType 枚举类中,常用的有:

  1. ElementType.TYPE可以用于类、接口、枚举类上
  2. ElementType.FIELD可以作用于类的属性上
  3. ElementType.METHOD可以作用于类的方法上
  4. ElementType.PARAMETER作用于类的参数上

如果想要同时作用于类和方法上:

@Target({ElementType.TYPE, ElementType.METHOD})
1.2 Retention

java.lang.annotation.Retention,自身也是一个注解,用于声明该注解的生命周期,它的值定义在java.lang.annotation.RetentionPolicy枚举类中,有三个值可以选择:

  1. SOURCE:纯注释作用
  2. CLASS:在编译阶段有效
  3. RUNTIME:在运行时有效
@Retention(RetentionPolicy.RUNTIME)
1.3 @interface

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

1.4 Annotation 属性
String value() default "";

约定了属性的类型和属性名称,default 代表的是默认值

2. Spring Bean

IoC(控制反转)容器是 Spring 框架最核心的组件,没有 IoC 容器就没有 Spring 框架。在 Spring 框架中,主要通过**依赖注入(DI)**来实现 IoC 。所有的 Java 对象都会通过 IoC 容器转变为 Bean(Spring 对象的一种称呼)。基本上所有的 Bean 都是由 接口+实现类 完成的,用户想要获取 Bean 的实例直接从 IoC 容器获取就可以了,不需要关心实现类。
在这里插入图片描述
org.springframework.context.ApplicationContext接口类定义容器的对外服务,通过这个接口,我们可以轻松的从 IoC 容器中得到 Bean 对象。在启动 Java 程序的时候必须先要启动 IoC 容器,Annotation 类型的 IoC 容器对应的类是org.springframework.context.annotation.AnnotationConfigApplicationContext,如果要启动 IoC 容器,可以运行下面的代码:

//启动 IoC 容器
ApplicationContext context = new AnnotationConfigApplicationContext("fm.douban"); //填写的是包名

这段代码的意义就是启动 IoC 容器,自动加载包 fm.douban 下的 Bean(只要是应用了 Spring 注解的类都可以被加载,前提是在这个包下面)。
Spring 官方声明为 Spring Bean 的注解有以下几种:

  1. org.springframework.stereotype.Service
  2. org.springframework.stereotype.Component
  3. org.springframework.stereotype.Controller 作用于 Web Bean
  4. org.springframework.stereotype.Repository 作用于持久化相关 Bean

只要我在类上引用这类注解,那么都可以被 IoC 容器加载。
依赖注入的第一步是完成容器的启动,第二部就是真正的完成依赖注入行为了。
依赖注入让我们得到其他 Bean 的实例相当简单,只需要在属性上添加注解。

例如:

import org.springframework.beans.factory.annotation.Autowired;

@Autowired
private SongService songService;

当然,还有一个前提:当前类是 Spring Bean,在本类上添加 @Service

3. Spring Resource

处理文件的方案 Spring Resource,在 Java 工程中文件的几种情况:

  1. 文件在电脑的某个位置,比如 d:/mywork/a.doc
  2. 文件在工程目录下,比如 mywork/tuo.png
  3. 文件在工程的 src/main/resource 目录下

在第三种情况下,jar 文件是从包路径开始的,Maven 工程编译后,会自动去掉 src/main/javasrc/main/resource目录。
问题:如何读取 jar 内部的文件?
方案:classpath 指定的文件不能解析成 File 对象,但是可以解析成 InputStream,我们借助 Java IO 就可以读出来了。classpath 类似虚拟目录,它的根目录是从 / 开始代表的是src/main/java或者src/main/resource目录
先要添加依赖:

<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
  <version>2.6</version>
</dependency>```
import java.io.IOException;
import java.io.InputStream;

public class Test {
  public static void main(String[] args) {
    // 读取 classpath 的内容
    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();
    }
  }
}

InputStream in = Test.class.getClassLoader().getResourceAsStream("data.json");这段代码的含义就是从 Java 运行的类加载器(ClassLoader实例中查找文件,Test.class指的是当前的 Test.java 编译后的 Java class 文件
在 Spring 当中定义了一个 org.springframework.core.io.Resource类来封装文件,这个类的优势在于可以支持普通的 File 也可以支持 classpath 文件,并且在 Spring 中通过 org.springframework.core.io.ResourceLoader服务来提供任意文件的读写,可以在任意的 Spring Bean 中引入ResourceLoader
创建一个自己的 FIleService:

public interface FileService {
    String getContent(String name);
}

实现类:

import fm.douban.service.FileService;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;

@Service
public class FileServiceImpl implements FileService {
    @Autowired
    private ResourceLoader loader;
    @Override
    public String getContent(String name) {
        try {
            InputStream in = loader.getResource(name).getInputStream();
            return IOUtils.toString(in,"utf-8");
        } catch (IOException e) {
           return null;
        }
    }
}

此服务的调用:

ApplicationContext context = new AnnotationConfigApplicationContext("fm.douban");
FileService fileService = context.getBean(FileService.class);
String content = fileService.getContent("classpath:data/urls.txt");
System.out.println(content);

在 Spring Resource 当中,把本地文件、classpath文件、远程文件都封装成 Resource 对象来统一加载,这就是它强悍的地方

4. Spring Bean 的生命周期

里面有一个 init 方法,名称是任意的,我们是通过注解来声明 init 的

import javax.annotation.PostConstruct;

@Service
public class SubjectServiceImpl implements SubjectService {
  @PostConstruct
  public void init(){
      System.out.println("启动啦");
  }
}  

只要在方法上添加 @PostConstruct注解,代表该方法在 Spring Bean 启动后会自动执行

点击Spring MVC

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值