Lite模式和Full模式是指在软件或系统中的不同配置选项。一般来说,Lite模式是指较为简洁、轻量级的配置,而Full模式则是指更加完整、功能更丰富的配置。
Lite模式通常会去除一些不常用或占用资源较多的功能,以提高系统的运行效率和响应速度。这样可以在资源有限或对系统性能要求较高的情况下使用,比如在低配置的计算设备上或移动设备上。
Full模式则包含了系统或软件的所有功能和特性,同时可能会占用更多的内存和处理器资源。这样可以满足用户对更多功能和高级选项的需求,适合在高配置的计算设备上使用。
选择Lite模式还是Full模式取决于用户的需求和使用场景。如果用户需要更快的响应速度和轻量级的操作体验,或者使用的是资源受限的设备,那么Lite模式可能更适合。而如果用户需要更多功能和高级选项,并且使用的是高配置的设备,那么Full模式可能更适合。
需要注意的是,Lite模式和Full模式的具体配置内容可能因软件或系统而异,用户在选择时应根据具体情况进行判断和比较。

-
-
- <dependencies>
-
- <dependency>
- <groupId>org.springframeworkgroupId>
- <artifactId>spring-contextartifactId>
- <version>5.3.23version>
- dependency>
-
- <dependency>
- <groupId>ch.qos.logbackgroupId>
- <artifactId>logback-classicartifactId>
- <version>1.4.5version>
- dependency>
-
- dependencies>
UserService 接口
- public interface UserService {
-
- void add();
-
- }
UserServiceImpl 实现类
- @Slf4j
- public class UserServiceImpl implements UserService {
- @Override
- public void add() {
- log.info("添加用户");
- }
- }
- @RequiredArgsConstructor
- public class UserController {
-
- private final UserService userService;
-
- public void addUser() {
-
- userService.add();
- }
-
- }
这段代码使用了Lombok库中的@RequiredArgsConstructor注解,该注解会生成一个带有final修饰的构造方法,用于对类中的final属性进行初始化。在这段代码中,通过使用@RequiredArgsConstructor注解实现了UserController类的构造方法,在构造方法中初始化了userService属性,避免了手动编写构造方法的繁琐。
需要注意的是,使用@RequiredArgsConstructor注解时,必须保证被注解的属性为非空(final)属性,否则在编译时就会出现错误。因此,在使用该注解时,需要仔细检查每一个被注解的属性是否满足要求。
-
- @Slf4j
- @Configuration
- public class AppConfig {
-
- /**
- * 装配 Usersevice
- *
- * @return
- */
- @Bean
- public UserService userService() {
- return new UserServiceImpl();
- }
-
- /**
- * 装配 UserController 并注入 UserService
- *
- * @return
- */
- @Bean
- public UserController userController() {
-
- // 得到需要注入的 Bean
- UserService userService = userService();
- log.info("1:" + userService);
- UserService userService1 = userService();
- log.info("2:" + userService1);
- // 将 bean 通过构造方法注入
- return new UserController(userService);
- }
-
- }
这段代码是一个使用Spring框架的Java配置类,其中包含了两个@Bean方法用于将UserService和UserController装配到Spring容器中。
在方法userService()中,使用@Bean注解声明一个UserService的实例,并返回该实例。该方法会在Spring容器启动时被调用,将UserService加入到Spring容器中。
在方法userController()中,同样使用@Bean注解声明一个UserController的实例,并注入一个UserService的实例。在这个方法内部,通过调用userService()方法来获取已经装配到Spring容器中的UserService实例。然后,将得到的UserService实例作为参数传递给UserController的构造方法,创建并返回UserController的实例。
需要注意的是,在这段代码中,还使用了Lombok库中的@Slf4j注解,用于自动生成日志记录器。通过在类上添加该注解,可以在Bean方法中使用log记录日志,避免手动编写日志记录器带来的繁琐。
@Configuration注解是Spring框架中的一个核心注解,用于标识一个类为配置类。配置类主要用于定义和组织Bean的创建和装配过程。具体来说,
@Configuration注解通常与@Bean注解一起使用。在一个带有@Configuration注解的类中,可以使用@Bean注解声明方法,并将该方法返回的对象注册为一个Bean。Spring容器在启动时会扫描这些类,并实例化这些Bean并将其添加到容器中。
- public class Main {
-
- public static void main(String[] args) {
- ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
- UserController bean = context.getBean(UserController.class);
- bean.addUser();
- }
-
- }
运行结果

此时,可以看到我们输出的 userservice 和 userservice1 的地址是一样的,因为使用了代理模式,使用了 @Configuration 默认情况下,当
proxyBeanMethods设置为true时,Spring容器会将@Bean注解的方法的返回值缓存起来作为单例对象。这样可以确保每次获取该Bean都是同一个实例,提高了性能和一致性。
-
- @Slf4j
- @Configuration(proxyBeanMethods = false)
- public class AppConfig {
-
- /**
- * 装配 Usersevice
- *
- * @return
- */
- @Bean
- public UserService userService() {
- return new UserServiceImpl();
- }
-
- /**
- * 装配 UserController 并注入 UserService
- *
- * @return
- */
- @Bean
- public UserController userController() {
-
- // 得到需要注入的 Bean
- UserService userService = userService();
- log.info("1:" + userService);
- UserService userService1 = userService();
- log.info("2:" + userService1);
- // 将 bean 通过构造方法注入
- return new UserController(userService);
- }
-
- }
@Configuration(proxyBeanMethods = false)禁用了代理模式。在这种情况下,Spring容器将不会使用CGLIB动态代理来创建userService()和userController()方法返回的Bean实例。对于
userService()方法,它没有任何依赖关系,每次调用都返回新的UserServiceImpl实例,无需代理。对于
userController()方法,它依赖于userService()方法返回的Bean实例。由于禁用了代理模式,每次调用userService()方法时都会返回一个新的实例,并且这个实例会被注入到UserController的构造方法中。所以,在日志输出中看到的
userService和userService1的值是不同的,它们引用的是不同的UserServiceImpl对象。通过禁用代理模式,您可以确保每个Bean都是原始的实例,并且不存在代理对象的干扰。
- public class Main {
-
- public static void main(String[] args) {
- ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
- UserController bean = context.getBean(UserController.class);
- bean.addUser();
- }
-
- }
运行结果


这个警告信息的意思是,您在一个
@Configuration配置类中使用了@Bean注解的方法,并且将proxyBeanMethods设置为false,这可能会导致一些问题。
proxyBeanMethods是@Configuration注解的一个属性,用于指定是否使用代理模式来管理@Bean注解的方法中创建的对象,默认值为true。当设置为true时,Spring容器将使用CGLIB动态代理来管理这些@Bean注解的方法和它们依赖的其他Bean。当设置为false时,Spring容器将直接调用该方法并返回该方法的返回值作为Bean实例。如果您将
proxyBeanMethods设置为false,则表示您不希望使用代理模式来管理Bean,但是同时使用@Bean注解的方法将直接调用,而没有使用Spring容器来管理这些Bean,这可能会导致一些问题。例如,有些Bean之间可能会产生循环依赖问题,导致应用程序无法启动。为了避免这个问题,建议您将
proxyBeanMethods设置为true,或者尽可能使用依赖注入,而不是直接调用@Bean注解的方法。但是呢,并不会影响程序的正常运行。
代理模式和禁用代理模式的主要区别在于Spring容器处理@Bean注解的方法时所采用的方式。
当proxyBeanMethods设置为true时,Spring容器会使用CGLIB动态代理来管理@Bean注解的方法和它们之间的依赖关系。
当proxyBeanMethods设置为false时,Spring容器不使用代理,直接调用@Bean注解的方法并返回该方法的返回值作为Bean实例。
循环依赖解决:如果存在循环依赖,代理模式可以通过提前暴露代理对象来解决循环依赖问题。代理对象可以在被依赖之前就可以被注入,从而解决了循环依赖的限制。
单例对象缓存:默认情况下,当
proxyBeanMethods设置为true时,Spring容器会将@Bean注解的方法的返回值缓存起来作为单例对象。这样可以确保每次获取该Bean都是同一个实例,提高了性能和一致性。
循环依赖无法解决:如果存在循环依赖,则会导致应用程序无法启动。
缺少单例对象缓存:由于每次调用
@Bean注解的方法都会返回一个新的实例,因此可能会导致性能问题或意外的行为。
因此,通常情况下建议使用代理模式,并将proxyBeanMethods设置为true,默认就是 true。
B类
- /**
- * @Date 2023-10-08
- * @Author qiu
- *
- * 目标对象(被代理的对象)
- */
- @Slf4j
- public class B {
-
- public void say() {
- log.info("Hello world!");
- }
-
- }
BProxy 类
- /**
- * @Date 2023-10-08
- * @Author qiu
- *
- * 代理对象
- */
- @Slf4j
- public class BProxy {
-
- /**
- * 声明一个被代理的对象
- */
- private B b;
-
- public BProxy(B b) {
- this.b = b;
- }
-
- public void say() {
- // 目标方法前
- before();
-
- // 调用目标对象的 say 方法
- b.say();
-
- // 目标方法后
- after();
- }
-
- /**
- * 调用目标方法前要执行的逻辑
- */
- private void before() {
- log.info("调用目标之前执行的业务逻辑.....");
- }
-
- private void after() {
- log.info("调用目标之后执行的业务逻辑.....");
- }
-
- }
- public class A {
-
- public static void main(String[] args) {
- // 创建代理对象
- BProxy bProxy = new BProxy(new B());
- bProxy.say();
-
- }
-
- }
运行结果

在这个示例中,
BProxy类是B类的代理类。代理类持有一个被代理对象b的引用,并且在调用say()方法时,会在目标方法前后执行额外的逻辑。
BProxy类中的before()方法和after()方法分别代表了目标方法调用前和调用后需要执行的逻辑。在say()方法中,首先会执行before()方法,然后调用被代理对象b的say()方法,最后再执行after()方法。在
A类的main方法中,创建了一个BProxy对象,并调用其say()方法。由于BProxy是B类的代理类,因此在调用say()方法时,额外的逻辑会被执行。通过静态代理模式,我们可以在不修改原始类
B的情况下,对其进行功能扩展或增强。这种方式可以在一些场景下提供更灵活的控制和定制逻辑。

所谓的代理就是可以理解为是一个中间类(中介),当我们需要调用 B 类的方法时,我们通过一个代理类来调用 B 类的方法,为什么需要代理类呢,是因为当我们调用 B 类的方法时需要增加其他的业务逻辑,但是又不能对 B 类去修改,所以使用代理类,在代理类中调用 B 类的方法,并且在代理类中调用 say 方法时,在之前和之后都做了相应业务逻辑处理。而我们用户调用的还是 say 方法,用户不用关心代理类中做了什么事情,它只关注它调用的是它想要的方法即可。
代理类:就是在调用目标对象的方法时,对目标对象的方法进行了增强或者修改。
配置类 Lite 模式(非代理模式)和 Full 模式(代理模式)
* 当配置类上标注了 @configuration 注解时,并且 proxyBeanMethods
* 属性设置为 true,此时就是 Full 模式,Full 模式就是 Spring 会为当前
* 配置类创建一个代理对象,从而创建配置类中所有的 @Bean 注解的方法
* 这样每当调用配置类只能的 Bean 方法之前,会从容器中进行检查 Bean 实例,
* 并返回容器中存在的 Bean 对象。
* 反之就是 Lite 模式,Lite 模式下配置类并不会被代理。每次调用 Bean
* 方法只是纯粹的调用,并不会经过代理。
Lite 模式(非代理模式)就是:@Configuration(proxyBeanMethods = false)
Full 模式(代理模式)就是:@Configuration