NET2Java之十三:Spring IOC
IoC是Spring框架的核心思想之一,用于降低代码之间的耦合度。
常用注解
想使用Spring来管理对象依赖,通常使用注解来实现,常用注解如下:
Component
- 作用:标记一个类为Spring管理的组件(Bean),会被Spring自动扫描并注册到IoC容器。
- 初始化:默认是单例(Singleton),如果需要多实例,需要额外添加Scope。
@Component
@Scope("prototype") // 每次注入或获取时都创建新实例
public class MyComponent {
// ...
}
Configuration&&Bean
- 作用:标记一个类为配置类,通常用于定义@Bean方法,替代XML配置,该类会被Spring扫描,并用于构建用用上下文。
- 特点:@Bean方法默认单例,myService()方法,仅在第一次需要注入 MyService时调用一次,通常用于引入第三方库的Bean。
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyService();
}
}
Repository
- 作用:标记一个类为数据访问层(DAO),是Component的特化版本。
- 特点:默认单例,主要用于数据库操作,会自动处理数据异常。
@Repository
public class UserRepository {
// JPA/MyBatis 操作
}
Service
- 作用:标记一个类为业务逻辑层
- 特点:通常包含业务逻辑,调用@Repository进行数据操作
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public void saveUser(User user) {
userRepository.save(user);
}
}
Controller
- 作用:标记一个类为Web控制器,处理HTTP请求
- 特点:默认单例,通常与 @RequestMapping、@GetMapping、@PostMapping等配合使用,返回视图或 REST API 数据。
@Controller
public class UserController {
@GetMapping("/users")
public String listUsers(Model model) {
model.addAttribute("users", userService.findAll());
return "users";
}
}
ResetController
- 作用:@Controller+ @ResponseBody,用于REST API,直接返回 JSON/XML 数据。
@RestController
@RequestMapping("/api/users")
public class UserApiController {
@GetMapping
public List<User> getAllUsers() {
return userService.findAll();
}
}
注入技巧
只有通过 Spring 容器创建和管理的对象(如 @Component、@Service、@Bean等),Spring 才会自动处理 @Autowired依赖注入,比如:
@Service
public class MyService {
@Autowired
private MyRepository myRepository; // 依赖注入
public void doSomething() {
if (myRepository == null) {
System.out.println("myRepository 是 null!");
} else {
System.out.println("myRepository 已注入");
}
}
}
// 测试代码
public class Main {
public static void main(String[] args) {
MyService myService = new MyService(); // 直接 new,而不是从 Spring 获取
myService.doSomething(); // 输出:"myRepository 是 null!"
}
}
这个示例中,myRepository为null,因为其绕过了Spring的依赖注入机制,可以通过ApplicationContextAware来实现使用时注入:
@Component
public class SpringContextHolder implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static <T> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}
public static <T> T getBean(String name, Class<T> beanClass) {
return context.getBean(name, beanClass);
}
}
使用:
public class MyService {
private LLMService llmService;
public MyService () {
llmService = SpringContextHolder.getBean(LLMService.class);
}
}
静态变量的注入
在非静态方法中注入依赖,然后在 @PostConstruct方法中赋值给静态变量,@PostConstruct会在 Bean 初始化完成后执行,此时 myRepository已经被 Spring 注入。
@Service
public class MyService {
private static MyRepository myRepositoryStatic; // 静态变量
@Autowired
private MyRepository myRepository; // 非静态注入
@PostConstruct
public void init() {
myRepositoryStatic = myRepository; // 初始化静态变量
}
public static void doSomething() {
if (myRepositoryStatic != null) {
myRepositoryStatic.queryData();
}
}
}

浙公网安备 33010602011771号