参考了 Spring Framework - Core,方便 Java 开发者快速入门 Spring Framework
前置知识:IoC, DI, AOP, Java EE (Jakarta EE)
IoC container and Bean
基于 IoC 和 DI 的思想,springframework 为你提供了 ApplicationContext (IoC container) 来产生和管理你需要的 Bean (Java Object),简单来说你不需要使用 new
一个 Object
MyObject myobject = new MyObject();
只需要从 IoC container 那儿获取
MyObject myobject = IoCcontainer.get(MyObject.class);
XML configuration
当然,springframework 不会让你这么写,它会让你写配置文件(configuration file),一般为 .xml
文件,ApplicationContext 会读取这些配置来产生 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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here -->
</beans>
在这个文件中
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
称之为 Bean 定义(Bean Definition)
这样 ApplicationContext 就可以读配置
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
当然,如果你想知道配置文件开头的一大段内容,建议去看 XML 规范和 Spring 文档。
Bean
Bean 在 ApplicationContext 中也有各种各样的 property。
Property | Explained in… |
---|---|
Class | Instantiating Beans |
Name | Naming Beans |
Scope | Bean Scopes |
Constructor arguments | Dependency Injection |
Properties | Dependency Injection |
Autowiring mode | Autowiring Collaborators |
Lazy initialization mode | Lazy-initialized Beans |
Initialization method | Initialization Callbacks |
Destruction method | Destruction Callbacks |
当然你想用这些 property,你得在 XML 中填写对应的 attribute
XML 中的 attribute
如果你要用一个 Bean,那么 ID 和 Class 必须写。
Dependency Injection
假如你有一个 MessageProcessor 想用(依赖)MessageService,那么你就需要使用 DI,他有两种方式,Constructor arguments (constructor-arg
) 或者 Properties (property
),前者是 Constructor-based DI,后者是 setter-based DI,看你喜欢用哪个,我推荐 Constructor arguments,下面举例:
public class MessageProcessor {
private MessageService messageService;
public MessageProcessor(MessageService messageService) {
this.messageService = messageService;
}
public void processMessage(String message) {
messageService.sendMessage(message);
}
}
在配置文件中
<bean id="emailService" class="com.example.EmailService"></bean>
<bean id="messageProcessor" class="com.example.MessageProcessor">
<constructor-arg ref="emailService" />
</bean>
Properties 就不多说了,自己看官方文档。
Property: Autowiring mode
Bean 有个 property 叫做 Autowiring mode,它可以设置 DI 的模式,一共有三种模式 no
,byName
,byType
,具体看官方文档。
Annotation-based Container Configuration
当然,用 XML 配置依赖属实有点难受,写的我头昏,spring framework 就提供了一个更好的配置方法,基于 Java annotation。
当然,你要用这个东西,你得更改你的 XML 文件来开启 annotation 配置,根据下面所写的内容,如果你的 XML 文件没有就加上。
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
现在我们进行 DI 就不用写 XML 啦,直接在 constructor 上写 @Autowired
annotation,舒服麻了。
public class MessageProcessor {
private MessageService messageService;
@Autowired
public MessageProcessor(MessageService messageService) {
this.messageService = messageService;
}
public void processMessage(String message) {
messageService.sendMessage(message);
}
}
配置文件中:
<bean id="emailService" class="com.example.EmailService"></bean>
<bean id="messageProcessor" class="com.example.MessageProcessor"></bean>
The
@Autowired
,@Inject
,@Value
, and@Resource
annotations are handled by SpringBeanPostProcessor
implementations.
@Autowired and @Resource
@Autowired 由 Spring annotation 提供,DI 模式默认 byType
@Resource 由 Jakarta annotation 提供,DI 模式默认为 byName
Classpath Scanning and Managed Components
如果你要用一个 Bean 需要在 XML 中定义,但是现在 spring framework 根据 MVC 结构还提供了下面的 annotation
- @Component
- @Service
- @Controller
- @Repository
这些 annotation 就能直接定义 Bean,太裤辣。
@Service
public class MessageProcessor {
private MessageService messageService;
@Autowired
public MessageProcessor(MessageService messageService) {
this.messageService = messageService;
}
public void processMessage(String message) {
messageService.sendMessage(message);
}
}
XML 配置可以直接替换成以下内容,注意 org.example
换成自己的!
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="org.example"/>
</beans>
The use of
<context:component-scan>
implicitly enables the functionality of<context:annotation-config>
. There is usually no need to include the<context:annotation-config>
element when using<context:component-scan>
.
End
spring framework core 到这里就结束了,其他功能看看文档就行了。
如果想继续去学 Web,可以去看