# @Eable * 注解
SpringBoot 中提供了很多 Enable 开头的注解,这些注解都是用于动态启用某些功能的。而其底层原理是使用 @Import 注解导入一些配置类,实现 Bean 的动态加载。
<span alt='solid'> 思考 </span>:
SpringBoot 工程是否可以直接获取 jar 包中定义的 Bean?
答案:不可以
如果不可以这个地方问题就非常严重了。比如说 redisTemplate 获取,是不是人家 jar 包里面定义的 Bean 啊。那为什么我的工程引入了 redis 的起步依赖我就直接可以获取到了呢 ?
首先演示不能获取第三方 jar 包里面定义的 Bean 的特点:
创建一个父模块,两个同级子模块
将 enable-other 模块导入到 enable 模块中使用
<dependency> | |
<groupId>com.dkx</groupId> | |
<artifactId>SpringBoot-enable-other</artifactId> | |
<version>0.0.1-SNAPSHOT</version> | |
</dependency> |
install,enable-other 模块否则报错找不到 XXX 类
编写 enable 模块
import org.springframework.boot.SpringApplication; | |
import org.springframework.boot.autoconfigure.SpringBootApplication; | |
import org.springframework.context.ConfigurableApplicationContext; | |
// @ComponentScan 扫描范围:当前引导类所在包及其子包 | |
// com/dkx1 | |
// com/dkx | |
// 1. 使用 @ComponentScan 扫描,com.dkx. 包 | |
// 2. 可以使用 @Impoert 注解,加载类 | |
@SpringBootApplication | |
public class SpringBootEnableApplication { | |
public static void main(String[] args) { | |
ConfigurableApplicationContext run = SpringApplication.run(SpringBootEnableApplication.class, args); | |
Object user = run.getBean("user"); | |
System.out.println(user); | |
} | |
} |
项目结构:
编写 enable-other 模块
config/UserConfig
@Configuration | |
public class UserConfig { | |
@Bean | |
public User user() { | |
return new User(); | |
} | |
} |
domain / User
public class User { } |
项目结构:
运行结果:
# 第一种方式
报错找不到 user 这个 Bean,我们可以通过下面的方式来解决。
首先要知道这个问题其实很简单,规则是子模块中路面相同的话就不会报错了,可以理解为两个模块可以看做一个模块的目录来构建就不会报错了。
import com.dkx.config.UserConfig; | |
import org.springframework.boot.SpringApplication; | |
import org.springframework.boot.autoconfigure.SpringBootApplication; | |
import org.springframework.context.ConfigurableApplicationContext; | |
import org.springframework.context.annotation.ComponentScan; | |
import org.springframework.context.annotation.Import; | |
// @ComponentScan 扫描范围:当前引导类所在包及其子包 | |
// com/dkx1 | |
// com/dkx | |
// 1. 使用 @ComponentScan 扫描,com.dkx. 包 | |
// 2. 可以使用 @Impoert 注解,加载类 | |
@SpringBootApplication | |
@ComponentScan("com.dkx.config") | |
//@Import(UserConfig.class) | |
public class SpringBootEnableApplication { | |
public static void main(String[] args) { | |
ConfigurableApplicationContext run = SpringApplication.run(SpringBootEnableApplication.class, args); | |
Object user = run.getBean("user"); | |
System.out.println(user); | |
} | |
} |
运行结果:
# 第二种方式
使用自定义注解的方式在自定义注解类使用 Import 导入 UserConfig 类然后在启动类中添加该自定义注解 简化获取 User 对象的操作
User
public class User { } |
UserConfig
@Configuration | |
public class UserConfig { | |
@Bean | |
public User user() { | |
return new User(); | |
} | |
} |
EnableUser
@Target(ElementType.TYPE) | |
@Retention(RetentionPolicy.RUNTIME) | |
@Documented | |
@Import(UserConfig.class) | |
public @interface EnableUser { | |
} |
启动类
// @ComponentScan 扫描范围:当前引导类所在包及其子包 | |
// com/dkx1 | |
// com/dkx | |
// 两个路径同级路径项目可以被扫描到 | |
@SpringBootApplication | |
// 简化操作 | |
@EnableUser | |
public class SpringBootEnableApplication { | |
public static void main(String[] args) { | |
ConfigurableApplicationContext run = SpringApplication.run(SpringBootEnableApplication.class, args); | |
Object user = run.getBean("user"); | |
System.out.println(user); | |
} | |
} |
运行结果:
# 第三种方式
还可以更下目录来解决问题
目录结构:
启动类代码:
import org.springframework.boot.SpringApplication; | |
import org.springframework.boot.autoconfigure.SpringBootApplication; | |
import org.springframework.context.ConfigurableApplicationContext; | |
import org.springframework.context.annotation.ComponentScan; | |
// @ComponentScan 扫描范围:当前引导类所在包及其子包 | |
// com/dkx | |
// com/dkx | |
// 两个路径同级路径项目可以被扫描到 | |
@SpringBootApplication | |
public class SpringBootEnableApplication { | |
public static void main(String[] args) { | |
ConfigurableApplicationContext run = SpringApplication.run(SpringBootEnableApplication.class, args); | |
Object user = run.getBean("user"); | |
System.out.println(user); | |
} | |
} |
运行结果: