Article Directory
Java Bean 和 Spring Bean
Beans are objects.
Whether it is a Java Bean or a Spring Bean, it is for obtaining instantiated objects. Among the differences, the blog in this chapter uses a code case to illustrate.
Java Bean
Java Bean is a Java object. In Java, an object is defined to be new
instantiated.
class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Test {
public static void main(String[] args) {
User user = new User();
user.setName("香蕉");
System.out.println(user.getName());
}
}
Spring Bean
To test using Spring Bean, you need to introduce Spring dependency files.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.13.RELEASE</version>
</dependency>
XML create bean
Create a User.java class
package cn.linkpower.xml;
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
In the resources
Create the following file spring.xml
file and configure the specified 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"
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">
<!-- 1、定义bean(根据User中的构造方法生成bean对象)-->
<bean id="userBean" class="cn.linkpower.xml.User"></bean>
</beans>
Create a test class, add the specified spring.xml
file to the Spring container, implement object acquisition, set value and call, etc.
package cn.linkpower.xml;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("spring.xml");
//classPathXmlApplicationContext.setConfigLocation("spring.xml");
User userBean = classPathXmlApplicationContext.getBean("userBean", User.class);
userBean.setName("香蕉");
System.out.println(userBean.getName());
// 验证Spring的bean是单例!
// User userBean2 = classPathXmlApplicationContext.getBean("userBean", User.class);
// userBean2.setName("香蕉2");
// System.out.println(userBean.getName());
// System.out.println(userBean2.getName());
// System.out.println(userBean.getName());
}
}
@Bean Create Bean
The above operation, according to the bean object specified in the xml configuration, org.springframework.context.support.ClassPathXmlApplicationContext
is loaded into the spring container to achieve object generation and reference operations.
At the same time, @Bean
the generation of objects can also be implemented.
package cn.linkpower.beans;
import org.springframework.context.annotation.Bean;
public class UserConfig {
/**
* 采取 @Bean 的方式,构建一个 bean对象;<br/>
* 相当于 <bean id="getUser" class="cn.linkpower.beans.User" />
* @return
*/
@Bean
public User getUser(){
return new User();
}
}
To use AnnotationConfigApplicationContext
, load it into the container.
Test class writing
package cn.linkpower.beans;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
public static void main(String[] args) {
// 构建容器
//AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
// 加载、注册配置类
// annotationConfigApplicationContext.register(UserConfig.class);
//annotationConfigApplicationContext.refresh();
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(UserConfig.class);
// 获取对象
User getUser = annotationConfigApplicationContext.getBean("getUser", User.class);
getUser.setName("banana");
System.out.println(getUser.getName());
}
}
@CompantScan Create Bean
The above two methods both need to configure or write configuration classes to define or construct beans. If there are too many objects, you need to configure more.
In addition, it can also implement class definition operations based on scanning operations.
Write a scan operation tool class (create a class and add annotation operations). Of course, the SpringBoot project defaults to scan the scan startup class directory:
package cn.linkpower.beanScan;
import org.springframework.context.annotation.ComponentScan;
/**
* @ComponentScan 注解,扫描的是带有 @Component 的类,将其解析加载至spring容器中
*/
@ComponentScan("cn.linkpower.beanScan")
public class UserConfigScan {
}
The use of @ComponentScan
annotations, designated scanning 路径
, the carrying @Component
marked class, Spring loaded onto the vessel, if need be loaded into the class Spring container, you need to add the class specified in the Component
annotation.
package cn.linkpower.beanScan;
import org.springframework.stereotype.Component;
@Component
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Write the test class:
package cn.linkpower.beanScan;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
public static void main(String[] args) {
// 这里主要是加载带有 @ComponentScan 注解的类,实现扫描 @Component 显示或隐式标注的类
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(UserConfigScan.class);
// 默认类名驼峰规范,所以此处从容器获取类,使用user
User user = applicationContext.getBean("user", User.class);
System.out.println(user);
}
}
It is widely used in Springboot @ComponentScan
. Secondly, similar @Service
and other annotations have @Component
annotations marked.
Programmatic BeanDefinition
Spring bean object in the building, take xml 定义 bean
, @Bean 注解
, @Compant 注解
etc., are all 声明式
created bean object.
Spring also supports the 编程式
creation of instance objects, as shown below:
Need Spring to construct the instantiated bean class
无注解
.
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Test {
public static void main(String[] args) {
// 创建容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 执行一次refresh,否则报错
applicationContext.refresh();
// 描述一个bean
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClass(User.class);
// 将描述的bean,设置别名称,放入容器中
applicationContext.registerBeanDefinition("userBeanObj",beanDefinition);
// 从容器中获取bean
User userBeanObj = applicationContext.getBean("userBeanObj", User.class);
System.out.println(userBeanObj);
}
}
In the Spring source code, whether it is to use @Component
, @Bean
or xml 配置<bean />
, with its underlying implementation still or take BeanDefinition
programmatic building.
In addition, BeanDefinition
there are other attribute parameters available for class settings, such as 单例、多例
etc.
FactoryBean build bean
Create a class that needs to be instantiated using Spring ( 无@Component注解
):
package cn.linkpower.factoryBean;
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Write a factory class, in order to generate beans:
package cn.linkpower.factoryBean;
import org.springframework.beans.factory.FactoryBean;
public class UserFactory implements FactoryBean {
/**
* 生成对象
* @return
* @throws Exception
*/
public Object getObject() throws Exception {
return new User();
}
/**
* 对象的类型
* @return
*/
public Class<?> getObjectType() {
return User.class;
}
}
Write the test class:
package cn.linkpower.factoryBean;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
public static void main(String[] args) {
// 1、构建容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.refresh();
// 2、定义bean的修饰类
AbstractBeanDefinition abstractBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
// 添加一个类进去
abstractBeanDefinition.setBeanClass(UserFactory.class);
// 3、将已修饰的类放入容器中
applicationContext.registerBeanDefinition("userFactoryTest",abstractBeanDefinition);
//4、获取类
User user = applicationContext.getBean("userFactoryTest",User.class);
System.out.println(user);
// 这个是报错的!
//System.out.println(applicationContext.getBean("userFactoryTest",UserFactory.class));
// 如果想获取 UserFactory 对象,则需要 名称写为 &userFactoryTest
//System.out.println(applicationContext.getBean("&userFactoryTest",UserFactory.class));
}
}
[注意:]
Using
org.springframework.beans.factory.FactoryBean
modified beans, in fact, the spring container will generate two bean objects.
userFactoryTest—>User object bean
&userFactoryTest—>UserFactory class object bean
Use
org.springframework.beans.factory.FactoryBean
thegetObject()
indirect definition of a bean.
Supplier defines the bean
In the Spring framework, there is an operation of using Supplier to construct a bean. When the bean is initialized, a class initial data can be generated through the Supplier class. The case information is as follows:
package cn.linkpower.supplier;
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
New test class:
package cn.linkpower.supplier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import java.util.function.Supplier;
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.refresh();
// 通过这种方式 注册bean
//applicationContext.registerBean(User.class);
applicationContext.registerBean(User.class, new Supplier<User>() {
public User get() {
User user = new User();
user.setName("banana");
return user;
}
});
User user = applicationContext.getBean("user", User.class);
System.out.println(user.getName());
}
}