System.out.println(“是否为同一个对象实例:” + (userdao1 == userdao2));
}
运行结果:
继续修改xml配置文件,把scope="singleton"
改为scope="prototype"
,即表明,我们用其创建对象时,不是同一个对象实例
上面的测试代码不变,运行结果:
💨Bean标签实例化时机
小伙伴们可能就有疑问了,上面这两种方式是什么时候创建对象实例的呢?不要急,咱们慢慢道来。
为了方便效果的展现,我在UserDaoImpl类
的无参构造器中加入一句代码,用来区别创建实例的时机
public UserDaoImpl(){
System.out.println(“UserDaoImpl开始创建”);
}
🔥scope为singleton时
运行debug,点击F8
我们可以发现,从加载配置文件的时候就开始创建了对象实例
🔥scope为prototype时
运行debug,按下F8,发现控制台并没有打印“UserDaoImpl开始创建”
,说明配置文件并没有加载对象实例
再次按F8下一步
我们可以发现控制台终于打印了“UserDaoImpl开始创建”
🔥总结
当scope的取值为singleton时,当应用加载,创建容器时,对象就被创建了;当scope的取值为prototype时,当使用对象时,才创建新的对象实例。
💨Bean生命周期配置
在UserDaoImpl类
中添加两个方法
public void init(){
System.out.println(“初始化方法”);
}
public void destory(){
System.out.println(“销毁方法”);
}
修改xml配置文件,init-method:
指定类中的初始化方法名称,destroy-method:
指定类中销毁方法名称
<bean id=“userdao” class=“com.sht.dao.impl.UserDaoImpl”
scope=“singleton”
init-method=“init”
destroy-method=“destory”>
编写测试代码
public void test3(){
ApplicationContext context =
new ClassPathXmlApplicationContext(“applicationContext.xml”);
UserDao userdao1 = (UserDao) context.getBean(“userdao”);
System.out.println(userdao1);
UserDao userdao2 = (UserDao) context.getBean(“userdao”);
System.out.println(userdao2);
System.out.println(“是否为同一个对象实例:” + (userdao1 == userdao2));
//这里用来关闭容器
((ClassPathXmlApplicationContext) context).close();
}
运行结果:
从这个例子,相信大家可以自己推测出创建对象、初始化、方法调用以及销毁的先后顺序了
💨Bean实例化三种方式
🔥方式一:无参构造方法实例化(重点)
其实我们前面一直使用的就是这一种方法,但是需要注意的是,这种方法会根据默认无参构造方法来创建类对象,如果bean中没有默认无参构造函数,将会创建失败
🔥方式二:工厂静态方法实例化(了解)
创建一个静态工厂类,直接返回UserDaoImpl类
的对象实例
public class StaticFactory {
public static UserDao getUserDao(){
return new UserDaoImpl();
}
}
编写xml配置文件的bean,这里的class
属性值是静态工厂类对应的包的路径,factory-method
对应的属性值是类中的方法名
编写代码测试
public class UserDaoDemo {
public static void main(String[] args) {
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext(“applicationContext.xml”);
UserDao userdao = (UserDao) applicationContext.getBean(“userdao”);
userdao.save();
}
}
最终的运行结果还会是:“保存成功~~”
🔥方式三:工厂实例方法实例化(了解)
创建一个工厂类,同样返回UserDaoImpl类
的对象实例
public class DynamicFactory {
public UserDao getUserDao(){
return new UserDaoImpl();
}
}
编写xml配置文件的bean,这里的class
属性值是工厂类对应的包的路径,第一个bean可以得到工厂类的对象,再写一个bean,用来获取UserDaoImpl类
的对象实例。factory-bean
属性值代表从哪个工厂里面拿,factory-method
对应的属性值是类中的方法名
最终的运行结果也是:“保存成功~~”
💨总结
💨基本介绍
依赖注入(Dependency Injection):它是 Spring 框架核心 IOC 的具体实现。
在编写程序时,通过控制反转,把对象的创建交给了 Spring,但是代码中不可能出现没有依赖的情况。IOC 解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。
那这种业务层和持久层的依赖关系,在使用 Spring 之后,就让 Spring 来维护了。
简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。
💨Bean的依赖注入方式
🔥方式一:有参构造方法
前面讲的都是无参构造方法,现在讲讲有参构造方法。我们先创建一个UserService接口
和其实现类UserServiceImpl
public interface UserService {
void save();
}
public class UserServiceImpl implements UserService {
private UserDao userdao;
public UserServiceImpl(UserDao userdao) {
this.userdao = userdao;
}
@Override
public void save() {
userdao.save();
}
}
编写xml配置文件的bean,class属性值分别对应类下的包路径。<constructor-arg name="userdao" ref="userdao"></constructor-arg>
中name
属性值是相应set方法名的去掉set后的首字母小写,ref
是引入引入数据类型,即表示着对象属性的注入
🔥方式二:set方法
接口不变,改变一下UserServiceImpl 类
,需要注意的是,setUserdao()的权限是public,不能写成private哦
public class UserServiceImpl implements UserService {
private UserDao userdao;
//权限是public
public void setUserdao(UserDao userdao){
this.userdao = userdao;
}
@Override
public void save() {
userdao.save();
}
}
编写xml配置文件的bean,class属性我就不再说明了。重点讲解的是<property name="userdao" ref="userdao"></property>
;name
属性值是相应set方法名的去掉set后的首字母小写,ref
是引入引入数据类型,即表示着对象属性的注入;这里把UserDaoImpl类
的对象注入到UserServiceImpl类
中,就可以调用其save()
方法了
测试代码:
public void test5(){
ApplicationContext context =
new ClassPathXmlApplicationContext(“applicationContext.xml”);
UserService userService = (UserService) context.getBean(“userService”);
userService.save();
}
运行结果:
此外,set方法中有一个特殊的方法:P命名空间注入。其本质也是set方法注入,但比起上述的set方法注入更加方便,主要体现在配置文件中,如下:
引入xmlns:p="http://www.springframework.org/schema/p"
名称空间,其次p:userdao-ref
属性值是跟ref
对应的属性值的含义是一样的,这种方法可以作为了解
<beans xmlns=“http://www.springframework.org/schema/beans”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xmlns:p=“http://www.springframework.org/schema/p”
xsi:schemaLocation=“http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd”>
💨普通数据类型的注入
我用set方法的方式,讲解bean的依赖注入。继续在UserDaoImpl类
中添加两个基本数据类型和它们的set方法
private String name;
private Integer age;
public void setName(String name) {
this.name = name;
}
public void setAge(Integer age) {
this.age = age;
}
public void show() {
System.out.println(“名字是” + name + “的年龄是” + age);
}
修改xml配置文件的bean,name的属性值
代表着set方法的名,value的属性值
表示你想要填入的属性值
写一个测试类:
public void test7(){
ApplicationContext context =
new ClassPathXmlApplicationContext(“applicationContext.xml”);
UserDaoImpl contextBean = context.getBean(UserDaoImpl.class);
contextBean.show();
}
运行结果:
💨集合数据类型的注入
🔥List类型的注入
继续在UserDaoImpl类
中改动代码:
private List stringList;
public void setStringList(List stringList) {
this.stringList = stringList;
}
public void showStringList() {
System.out.println(stringList);
}
修改xml配置文件,注入基本数据类型就是两个关键字<list>
和<value>
111
222
333
运行结果:
🔥List类型的注入
先创建一个User类,有对应的get和set方法,还有toString方法,方便测试使用
public class User {
private Integer id;
private String username;
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return “User{” +
“id=” + id +
“, username='” + username + ‘’’ +
“, password='” + password + ‘’’ +
‘}’;
}
}
修改xml配置文件的bean,可以看出,与之前不同的是,<list>
中用的是<ref>
标签,这个标签表示的是注入引用数据类型
运行结果:
🔥Map<String,User> 类型的注入
继续在UserDaoImpl类
中改动代码:
private Map<String, User> stringUserMap;
public void setStringUserMap(Map<String, User> stringUserMap) {
this.stringUserMap = stringUserMap;
}
public void showStringUserMap() {
System.out.println(stringUserMap);
}
修改xml配置文件,与之前不同的是,当使用的是map时,标签用的是<map>
和标签<entry>
,使用方法跟list标签
差不多
运行结果:
需要注意的是,我们在选择key属性时,会有一个如图所示的key-ref的提示,这代表着我们要用的key是一个引入数据类型,因为我用的key是String,所以选择key
当使用value-ref时,也会出现value的值,其用法跟上面一样
🔥Properties类型的注入
继续在UserDaoImpl类
中改动代码:
private Properties properties;
public void setProperties(Properties properties) {
this.properties = properties;
}
public void showProperties(){
System.out.println(properties);
}
修改xml配置文件,与之前的不同之处就是标签使用的是<props>
和标签<prop>
,使用的方法也是跟上面的方法类似
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://i-blog.csdnimg.cn/blog_migrate/48535b8713934b5b67cf0a1b0ca8694d.jpeg)
最后
针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。
最新整理面试题
上述的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题
最新整理电子书
最新整理大厂面试文档
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
极易碰到天花板技术停滞不前!**
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-fENkFsUN-1713685460800)]
[外链图片转存中…(img-l05cIdRj-1713685460801)]
[外链图片转存中…(img-hpHMg0pc-1713685460801)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://i-blog.csdnimg.cn/blog_migrate/48535b8713934b5b67cf0a1b0ca8694d.jpeg)
最后
针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。
最新整理面试题
[外链图片转存中…(img-ACY6bC86-1713685460802)]
上述的面试题答案都整理成文档笔记。也还整理了一些面试资料&最新2021收集的一些大厂的面试真题
最新整理电子书
[外链图片转存中…(img-yGPHpBsk-1713685460802)]
最新整理大厂面试文档
[外链图片转存中…(img-hNntNQHB-1713685460803)]
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!