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属性没有被指定,则默认将会遵循驼峰命名法赋予默认值