三层架构

  • controller:控制层,接收前端发送的请求,对请求进行处理并响应数据
  • service:业务逻辑层,处理具体的业务逻辑
  • dao:数据访问层(持久层),负责数据访问操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//service层
package com.example.service;

import java.io.IOException;
import java.util.Map;


public interface PrintFileContentService {
Map<String,String> printContentFromUrlFile() throws IOException;
}

//serviceImpl
package com.example.service;

import com.example.dao.UrlFileDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@Service
public class PrintFileContentServiceImpl implements PrintFileContentService {
@Autowired
private UrlFileDao urlFileDao;

@Override
public Map<String,String> printContentFromUrlFile() throws IOException {
List<String> urls = urlFileDao.readAllUrls();
Map<String, String> result = new LinkedHashMap<>();

for (String urlStr : urls) {
if (urlStr == null || urlStr.trim().isEmpty()) {
continue;
}
try {
URL url = new URL(urlStr);
URLConnection con = url.openConnection();
StringBuilder content = new StringBuilder();
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(con.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
content.append(line).append("\n"); // 收集每一行
}
}
result.put(urlStr, content.toString());
} catch (Exception e) {
result.put(urlStr, "Error: " + e.getMessage());
}
}
return result;
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//dao层
package com.example.dao;

import java.io.IOException;
import java.util.List;

public interface UrlFileDao {
List<String> readAllUrls() throws IOException;
}


//daoImpl
package com.example.dao;

import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Repository;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

@Repository
public class UrlFileDaoImpl implements UrlFileDao {
private static final String URL_FILE_PATH="url.txt";

/**
*获取文件数据
*/
@Override
public List<String> readAllUrls() throws IOException {
ClassPathResource resource = new ClassPathResource(URL_FILE_PATH);
try(BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8))){
return reader.lines().toList();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//controller层
package com.example.controller;

import com.example.dao.UrlFileDao;
import com.example.service.PrintFileContentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.Map;

@RestController
public class PrintFileContentController {
@Autowired
private PrintFileContentService printService;

@GetMapping("/list")
public Map<String,String> PrintFileContent() throws IOException {
return printService.printContentFromUrlFile();
}

}

IOC容器管理

@RestController则是@Controller的衍生注解。

如果在声明bean的时候没有指定名字,默认使用类名首字母小写。

声明bean的注解想要生效需要被组件扫描注解@ComponentScan扫描。该注解被启动类声明注解@SpringBootApplication包含在其中,@SpringBootApplication默认扫描范围是启动类所在包及其子包。

DI(依赖注入)

基于@Autowired进行依赖注入的常见方式有三种:

  • 属性注入
1
2
3
4
5
6
@RestController
public class PrintFileContentController {
@Autowired
private PrintFileContentService printService;
//......
}
  • 构造函数注入

当只有一个构造函数时,@Autowired可以省略不写

1
2
3
4
5
6
7
8
@RestController
public class PrintFileContentController {
private final PrintFileContentService printService;
@Autowired
public PrintFileContentController(PrintFileContentService printService){
this.printService=printService;
}
}
  • setter注入
1
2
3
4
5
6
7
8
@RestController
public class PrintFileContentController {
private PrintFileContentService printService;
@Autowired
public setPrintFileContentController(PrintFileContentService printService){
this.printService=printService;
}
}

@Autowired注解默认是按照类型进行注入的,当存在多个相同类型的bean时会报错。

有三种方式能解决:

  • @Primary
1
2
3
4
5
6
7
@Primary
@Service
public class PrintFileContentServiceImpl implements PrintFileContentService {
@Autowired
private UrlFileDao urlFileDao;
//......
}
  • @Qualifier,注意首字母一定要小写
1
2
3
4
5
@RestController
public class PrintFileContentController {
@Autowired
@Qualifier("printFileContentServiceImpl")
private PrintFileContentService printService;
  • @Resource
1
2
3
4
@RestController
public class PrintFileContentController {
@Resource(name="printFileContentServiceImpl")
private PrintFileContentService printService;

@Autowired是spring框架提供的注解,@Resource是JavaEE规范提供的;

@Autowired默认按照类型注入,@Resource默认按照名称注入。