IOC详解
1、IOC创建对象方式
1.1、无参构造
<bean id="user" class="com.moral.pojo.User">
<property name="name" value="张三"/>
</bean>
1.2、下标(带参)
<bean id="user1" class="com.moral.pojo.User">
<constructor-arg index="0" value="李四"/>
</bean>
1.3、类型(带参)
<!--2.通过类型-->
<!--如果多个参数都是同一类型就不行,所以不建议使用-->
<bean id="user2" class="com.moral.pojo.User">
<constructor-arg type="java.lang.String" value="王五"/>
</bean>
1.4、参数名(带参)
<!--3.直接通过有参构造参数名-->
<bean id="user3" class="com.moral.pojo.User">
<constructor-arg name="name" value="赵六"/>
</bean>
1.5、测试
public class MyTest2 {
public static void main(String[] args) {
//Spring容器相当于婚介所,
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//1.无参构造
User user = (User) context.getBean("user");
System.out.println("user==" + user);//张三
/*2.有参*/
//1.下标
User user1 = (User) context.getBean("user1");
System.out.println("user1==" + user1);//李四
//2.类型,如果多个参数都是同一类型就不行,所以不建议使用
User user2 = (User) context.getBean("user2");
System.out.println("user2==" + user2);//王五
//3.通过有参构造参数名
User user3 = (User) context.getBean("user3");
System.out.println("user3==" + user3);//赵六
//容器中对象只有一个
User user4 = (User) context.getBean("user3");
User user5 = (User) context.getBean("user3");
System.out.println(user4 == user5);//true
}
}
1.6、总结
在配置文件加载时,容器中管理的对象已经初始化了
2、Spring配置
2.1、别名
<!--alias:别名,配置了别名,就可以通过别名获取对象-->
<alias name="user" alias="userAlias"/>
2.2、Bean的配置
<!--id:bean的唯一标示,相当于对象名-->
<!--bean对象所对应权限定名:包名+类名-->
<!--name:也是别名,还可以同时起多个别名,用空格,逗号,或分号分割-->
<bean id="userT" class="com.moral.pojo.User" name="u1,u2 u3;u3">
</bean>
2.3、import
一般用于团队开发,它可以将多个配置文件导入合并为一个。
假设3个人开发一个项目,不同的类需要注册在不同的bean中国,我们就可以用import将所有人的beans.xml合并为一个,使用时直接使用总的applicationContext.xml,如果相同的bean,则会变成一个
3、DI依赖注入
3.1、构造器注入(前面讲过)
3.2、Set注入(重点)
依赖:bean创建依赖于容器
注入:bean对象中的所有所有属性,由容器来注入
<bean id="address" class="com.moral.pojo.Address">
<property name="address" value="苏州"/>
</bean>
<bean name="student" class="com.moral.pojo.Student">
<!--1.普通注入-->
<property name="name" value="七七"/>
<!--2.bean注入,ref-->
<property name="address" ref="address"/>
<!--3.数组-->
<property name="books">
<array>
<value>貂蝉</value>
<value>西施</value>
<value>杨贵妃</value>
<value>王昭君</value>
</array>
</property>
<!--4.list-->
<property name="hobbys">
<list>
<value>篮球</value>
<value>电影</value>
<value>音乐</value>
</list>
</property>
<!--5.set-->
<property name="games">
<set>
<value>LOL</value>
<value>CF</value>
<value>DNF</value>
</set>
</property>
<!--6.map-->
<property name="card">
<map>
<entry key="身份证" value="123456"/>
<entry key="银行卡" value="asdf"/>
</map>
</property>
<!--7.null注入-->
<property name="wife">
<null/>
</property>
<!--7.Properties-->
<property name="info">
<props>
<prop key="driver">mysql</prop>
<prop key="url">www.baidu.com</prop>
<prop key="user">root</prop>
<prop key="pwd">123456</prop>
</props>
</property>
</bean>
3.3、拓展注入
p和c命名空间注入需要导入xml约束
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--p命名空间注入,对应set注入中的属性注入,实体类必须有无参构造-->
<bean id="user" class="com.moral.pojo.User" p:name="张三" p:age="18"/>
<!--c命名空间注入(Constructs),构造器有参注入,实体类必须有带参构造-->
<bean id="user1" class="com.moral.pojo.User" c:name="李四" c:age="22"/>
</beans>
4、bean的作用域
<bean id="address" class="com.moral.pojo.Address" scope="singleton">
</bean>
- 单例(默认)singleton 每次getBean都是同一个对象
- 原型:prototype 每次getBean都是不同对像
- request,session,application在web中开发才有用
5、bean的自动装配
装配方式:
- xml显式配置
- java中显式配置
- 隐式的自动装配
5.1、byName
<!--byName:会自动在容器上下文中查找,和自己对象的set方法后面的值对应的beanId-->
<bean id="people" class="com.moral.pojo.People" autowire="byName">
<property name="name" value="qiqi"/>
</bean>
5.2、byType
<!--buType:会自动在容器上下文中查找,和自己对象属性类型形同的bean,此时id可以省略-->
<bean id="people1" class="com.moral.pojo.People" autowire="byType">
<property name="name" value="jj"/>
</bean>
5.3、总结
byName时, 要保证所有bean的id唯一
byType时,要保证所有bean的Class唯一
5.4、注解自动装配
- 导入约束:context约束
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
- 开启注解支持
<context:annotation-config/>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="dog" class="com.moral.pojo.Dog"/>
<bean id="cat" class="com.moral.pojo.Cat"/>
<bean id="people" class="com.moral.pojo.People"/>
<!--开启注解支持-->
<context:annotation-config/>
</beans>
3.使用
private String name;
@Autowired
@Qualifier(value = "dog1")
//@Resource
private Dog dog;
@Autowired
@Qualifier(value = "cat1")
private Cat cat;
@Autowired:按类型注入,配合@Qualifier(value="xxx")可以实现类型相同时按name注入,用在属相上或者属性的set方法上
@Resource:先按name注入,找不到再按类型。
- 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
6、使用注解开发
Spring4之后,使用注解开发,必须导入aop依赖(直接导入spring-webmvc即可)
- 必须导入context约束
-
bean
-
属相如何注入
@Component public class User { public String name; /*相当于 *<property name="name1" value="jpy"/> 也可注解在属性上 * */ @Value("jpy") public void setName(String name) { this.name = name; } }
-
衍生注解
-
@Component
- dao层->@Repository
- service层->@Service
- controller层->@Controller
这四个注解功能一样,都是代表将某个类注册到Spring中,装备Bean
-
-
自动装配配置
- @Autowired通过类型装备,配合@Qualifier(value="xxx")实现通过名称装配
- @Resource先按name注入,找不到再按类型。
- @Nullable 注解字段,代表字段可以为null
-
作用域
@Scope("singleton")默认 单例
- singleton 单例
- prototype
-
小结
xml万能,便于维护注解 维护复杂
最佳实践:
-
xml管理bean
-
注解只负责完成属性注入
-
注解要生肖,必须开启注解支持
<!--开启注解支持--> <context:annotation-config/> <!--指定要扫描的包,此包下注解就会生效--> <context:component-scan base-package="com.moral"/>
-
7、使用java方式配置Spring
JavaConfig是spring子项目,spring4之后成为核心功能
7.1、实体类
@Component
public class User {
private String name;
public String getName() {
return name;
}
@Value("jpy")
public void setName(String name) {
this.name = name;
}
}
7.2、配置类
//本身就是一个@Component,代表这是一个配置类,和之前beans.xml一样
@Configuration
@ComponentScan("com.moral.pojo")
//引入其它配置类,合二为一
@Import(MyConfig2.class)
public class MyConfig {
//注册一个bean,相当于之前xml中bean标签
//方法名字相当于bean标签中的id属性
//返回值相当于bean标签中class属性
@Bean
public User getUser(){
return new User();
}
}
7.3、测试使用
@Test
public void test01(){
//完全使用了配置类方式去做,就只能通过AnnotationConfigApplicationContext来获取容器,通过配置类的class对象来加载
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
User user = (User) context.getBean("getUser");
System.out.println(user.getName());//jpy
Stu stu = (Stu) context.getBean("getStu");
System.out.println(stu.getAge());//18
}
7.4、总结
纯java的配置方式,在springboot中随处可见
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY