Springboot 6——对象管理单例&多例

根据编程不良人视频整理
springboot中的对象管理
工厂特性对象又分为单个对象和多个对象,对于单个对象的管理相对比较方便。
管理单个对象:在springboot中可以管理自定义的简单组件对象的创建可以直接使用注解形式的创建
使用@Repository @Service @Controller 以及@Component管理不同简单对象

之前在controller包中新建了HelloController.java类
现在在com.estella下新建service包->新建UserService.java接口

public interface UserService {
    
    
    void save(String name);
}

在service包下新建UserServiceImpl.java实现类
ctrl+O 相当于右键Generate->Override methods 重写接口中的方法
soutv 相当于打当前变量的名字
注意:需要在UserServiceImpl类上添加@Service注解,否则在HelloController.java中无法autowire UserService的对象,会报错。(autowire是自动配置的意思)通过添加@Service注解,直接创建了Service对象。

回到HelloController.java

在类中添加代码

@Autowired
    private UserService userService;

在hello方法中添加

userService.save("jenny");

管理多个对象
在springboot中如果要管理复杂对象必须使用@Configuratio+@Bean注解进行管理

@Configuration注解是用来配置的,可以一次性管理多个对象,无论是直接new的类还是抽象类接口类型的实例也可以交给它管理。
在com.estella.BeansConfig类中,之前已经建过该类
举例,在该类中新建一个日历对象,日历类本身就是一个抽象类,如果要做实例化的话,必须得通过调用它内部的静态方法去实例化,结合@Configuration注解需要在getCalendar方法前添加注解@Bean
@Bean用来将该方法的返回值交给springboot管理。原来我们用xml或者注解的方式进行创建对象的话,默认创建出来的对象在工厂中都有一个唯一的标识,以这种对象默认创建出来的标识,在工厂中默认标识:类名首字母小写。

@Bean
        public Calendar getCalendar(){
    
    
            return Calendar.getInstance();
        }

举例:当前的Calendar创建出来之后,实际上标识就是小写的calendar

注意:getInstance是一个函数,在java中,可以使用这种方式使用单例模式创建类的实例,所谓单例模式就是一个类有且只有一个实例。

创建之后就可以注入去用了。
在HelloController.java中添加

@Autowired
    private Calendar calendar;

在hello方法中写入

System.out.println(calendar.getTime());

运行程序控制台输出
Wed Oct 14 17:05:11 CST 2020

问题:这个在工厂中的名字是否可以改?
例如@Bean(name=“aaa”),这样的话日后在工厂中构建出来的对象名字为aaa,目前没有什么影响,但日后需要基于名字去获取的时候,就有用处了。但一般不建议修改,默认的方式还是比较好的。

观察@Bean这种方式是否是多例?
在HelloController.java类中添加代码

@Autowired
    private Calendar calendar1;

并在hello方法中添加

    System.out.println(calendar);
    System.out.println(calendar1);
    System.out.println(calendar==calendar1);

控制台输出结果:

java.util.GregorianCalendar[time=1602673750866,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2020,MONTH=9,WEEK_OF_YEAR=42,WEEK_OF_MONTH=3,DAY_OF_MONTH=14,DAY_OF_YEAR=288,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=2,AM_PM=1,HOUR=7,HOUR_OF_DAY=19,MINUTE=9,SECOND=10,MILLISECOND=866,ZONE_OFFSET=28800000,DST_OFFSET=0]
java.util.GregorianCalendar[time=1602673750866,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2020,MONTH=9,WEEK_OF_YEAR=42,WEEK_OF_MONTH=3,DAY_OF_MONTH=14,DAY_OF_YEAR=288,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=2,AM_PM=1,HOUR=7,HOUR_OF_DAY=19,MINUTE=9,SECOND=10,MILLISECOND=866,ZONE_OFFSET=28800000,DST_OFFSET=0]
true

比较结果是true,说明默认以单例的形式创建

问题:想要变为多例?
解决方法:在BeansConfig.java文件中的@Bean注解下加上注解@Scope()作用:用来设置在工厂中创建的对象是否是多例。

@Scope(”prototype“)多例

默认是singleton单例

改为多例后再次运行程序

java.util.GregorianCalendar[time=1602674570332,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2020,MONTH=9,WEEK_OF_YEAR=42,WEEK_OF_MONTH=3,DAY_OF_MONTH=14,DAY_OF_YEAR=288,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=2,AM_PM=1,HOUR=7,HOUR_OF_DAY=19,MINUTE=22,SECOND=50,MILLISECOND=332,ZONE_OFFSET=28800000,DST_OFFSET=0]
java.util.GregorianCalendar[time=1602674570332,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2020,MONTH=9,WEEK_OF_YEAR=42,WEEK_OF_MONTH=3,DAY_OF_MONTH=14,DAY_OF_YEAR=288,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=2,AM_PM=1,HOUR=7,HOUR_OF_DAY=19,MINUTE=22,SECOND=50,MILLISECOND=332,ZONE_OFFSET=28800000,DST_OFFSET=0]
false

false说明两个对象不同,即为多例

猜你喜欢

转载自blog.csdn.net/qq_42999949/article/details/109081152