Spring
第一个 Spring 项目
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.1.0</version>
</dependency>
在spring-config.xml
中定义一个Java Bean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean name="student" class="com.test.bean.Student"/>
</beans>
在Main
中获取Spring
上下文,并申请对象
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
Student student = context.getBean(Student.class);
student.hello();
}
Bean 注册与配置
Bean
在定义与获取时不能出现歧义,不同的Bean
的name
不能够相同
<bean name="student" class="com.test.bean.Student"/>
可以使用alias
标签为Bean
定义别名
<alias name="student" alias="stu"/>
在Spring
中,对象默认是以单例模式被创建的,可指定scope
为prototype
使其变更为原型模式(多例)
<bean name="student" class="com.test.bean.Student" scope="prototype"/>
也可以通过lazy-init
属性,使得Bean
在被需要时再创建
或使用depends-on
来指定加载顺序
依赖注入
属性注入
使用属性注入时,需要对应属性拥有其Setter
方法
<bean name="student" class="com.test.bean.Student">
<property name="stuName" value="Cherry"/>
<property name="stuAge" value="10"/>
<property name="stuId" value="10"/>
</bean>
构造器注入
可以使用constructor-arg
进行构造器注入,但是参数顺序需要和带参构造函数保持一致
Spring
将会自动匹配指定参数类型,指定参数数量的构造方法
<bean name="student" class="com.test.bean.Student">
<constructor-arg name="stuId" value="10"/>
<constructor-arg name="stuName" value="Cherry"/>
<constructor-arg name="stuAge" value="10" type="int"/>
</bean>
注入集合类型
Spring
对集合类型拥有特别的支持
<!-- List类型 -->
<bean name="student" class="com.test.bean.Student">
<property name="studentTeachers">
<list>
<value>A</value>
<value>B</value>
<value>C</value>
</list>
</property>
</bean>
<!-- Map类型 -->
<bean name="student" class="com.test.bean.Student">
<property name="studentTeachers">
<map>
<entry key="A" value="a"/>
<entry key="B" value="b"/>
<entry key="C" value="c"/>
</map>
</property>
</bean>
自动装配
可以开启自动装配,属性值将会由IoC
容器自动装配,同时也可以按属性名注入或者按构造器注入
<bean name="student" class="com.test.bean.Student" autowire="byType"/>
当Bean
发生歧义时,可以使用autowire-candidate
使得一个Bean
不参与自动注入,或者使用primary
使得Bean
被优先选择
生命周期与继承
可以使用init-method
和destory-method
方法指定初始化方法和销毁方法,能够在对象被初始化和销毁时调用指定的方法
<bean name="student" class="com.test.bean.Student" init-method="init" destroy-method="destroy">
需要注意的是,这种生命周期只对单例模式生效,而原型模式Spring
无法顾及其所有生命周期
继承
在Spring
中同样拥有继承,但这种继承是属性的继承,而不是类的继承
<bean name="student" class="com.test.bean.Student">
<property name="stuId" value="10"/>
<property name="stuName" value="Cherry"/>
<property name="stuAge" value="10"/>
</bean>
<bean name="student2" class="com.test.bean.Student" parent="student"/>
对于特殊的属性,可以使用属性注入的方式(property)特别指定
可以使用abstract
将一个Bean
定义为抽象Bean
,此时容器将不再为这个Bean
创建对象,而是将其作为Bean
的模板
如果希望给所有的Bean
应用默认配置,可以在最外层的beans
标签中定义
工厂模式和 Bean
在Spring
中,可以定义工厂,使得在创建Bean
时透过工厂来创建
若创建Bean
不需要实例化工厂类
<bean name="student" class="com.test.factory.StudentFactory" factory-method="getStudent"/>
System.out.println(context.getBean("student")); //直接获取Bean
若创建Bean
需要实例化工厂类
<bean name="studentFactory" class="com.test.factory.StudentFactory"/>
<bean factory-bean="studentFactory" factory-method="getStudent"/>
System.out.println(context.getBean("studentFactory"));
或者可以让其实现FactoryBean
接口
public class StudentFactory implements FactoryBean<Student> {
@Override
public Student getObject() {
return null;
}
@Override
public Class<?> getObjectType() {
return null;
}
}
值得注意的是,此时通过名称直接获取Bean
对象返回的将会是FactoryBean
所生产出的对象,若需要获取FactoryBean
本身可以加上&
符
StudentFactory studentFactory = (StudentFactory) context.getBean("&student");
使用注解开发
在Spring
中,可以使用配置类 + 注解 的方式代替配置文件
@Configuration
public class MainConfiguration {
@Bean("student")
public Student student() {
return new Student();
}
}
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MainConfiguration.class);
同时也可以通过@Import
注解来导入其它的配置类
可以在@Bean
注解中直接指定autowireCandidate
、initMethod
、destroyMethod
也能够使用@Lazy
、@DependsOn
、@Scope
等注解来修饰
对于需要使用到其他类的属性注入或者构造函数注入,可以直接将其作为参数放入构造方法中
自动装配
也可以使用@Autowired
来自动装配,它不仅仅能够用于字段,同时也能用于构造方法或Setter
@Autowired
默认使用byType
的方式装配,若出现了多个同类型的Bean
可以使用@Qualifier
按名称匹配
@Autowired
private Teacher stuTeacher;
Jakarta 中的注解
使用jakarta.annotation
中的注解需要额外导入依赖坐标
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.1</version>
</dependency>
@Resource
与@Autowired
的用法相同,但:
@Resouce
默认ByName
,找不到则ByType
,可以添加到Setter
、字段上
@Autowired
默认是ByType
,只会根据类型查找,可以添加到构造方法、Setter
、字段、方法参数上
@Resource
private Teacher stuTeacher;
此外还有@PostConstruct
和@PreDestroy
,它们的作用和init-method
和destroy-method
一致
@Compoent
@Compent
不同于@Bean
,将通过反射的方式来创建对象,但是需要配置包扫描
使用@Compoent
时,若构造函数不是默认无参构造,则默认会给每一个参数都进行自动注入
若name
属性没有被指定,则默认将会遵循驼峰命名法赋予默认值