在Spring框架中,Bean是核心概念之一,是Spring装配的组件模型。一切实体类都可以配置成一个Bean,进而就可以在任何其他的Bean中使用。一个Bean也可以不是指定的实体类,这就是抽象Bean。
在Spring中,构成应用程序主干并由Spring IoC容器管理的对象称为bean。bean是一个由Spring IoC容器实例化、组装和管理的对象。
bean属性和作用:
id:给对象在容器中提供一个唯一标识。用于获取对象。
class:指定类的全限定类名。用于反射创建对象。默认情况下调用无参构造函数。
scope:指定对象的作用范围。在Spring2.0之前,Bean只有两种作用域,即Singleton(单例)和non-Singleton(也称prototype)。Spring2.0以后,增加了session、request和global session三个专用于Web应用程序上下文的Bean。
同时,
启动 Spring 容器的时候就会创建所有的 bean(单例,可在实体类的无参构造中添加输出方法进行测试)
① 构造器实例化 – 无参构造器
实体类 – Student
public class Student{ public Student(){ System.out.println("实例化"); } }
配置文件 – spring-student.xml
测试类
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:spring-student.xml") public class StudentTest { @Autowired private Student s1; @Test public void student_test1(){ System.out.println(s1); } }
② FactoryBean 接口实例化
实体类 – Student
public class Student{ public Student(){ System.out.println("实例化"); } }
实现类 – StudentFactoryBean
// BeanFactory是一个工厂类接口 // 主要用于管理Bean,包括实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。 // 它通常用于从XML配置文件中加载bean定义,并且根据这些定义创建bean实例。 public class CatFactoryBean implements FactoryBean { @Override public Student getObject() throws Exception {//返回实体类对象 return new Student(); } @Override public Class> getObjectType() { return Student.class; } }
配置文件 – spring-student.xml
测试类
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:spring-student.xml") public class StudentTest { @Autowired private Student s1; @Test public void student_test1(){ System.out.println(s1); } }
Bean的作用域指的是Bean在Spring整个框架中的生命周期和作用范围。
① Singleton:单例作用域。该作用域下,Spring容器中只存在一个Bean实例,所有的请求都返回同一个Bean实例。这是Spring的默认选择的作用域,适用于不需要频繁新建和销毁Bean的情况。
② Prototype:原型作用域。每次请求时都会创建一个新的Bean实例。这种作用域下,Bean的生命周期很长,不易回收,通常需要进行额外的清除处理。
③ Request:请求作用域。每个HTTP请求都会创建一个新的Bean实例,该Bean实例仅在当前请求内有效。适用于一次HTTP请求和响应的共享Bean。
④ Session:会话作用域。每个HTTP会话都会创建一个新的Bean实例,该Bean实例仅在当前会话内有效。适用于用户回话的共享Bean,比如记录一个用户的登陆信息。
⑤ Application:全局作用域。一个Bean定义对应于单个ServletContext的生命周期。适用于Web应用的上下文信息,例如记录一个应用的共享信息。
⑥ WebSocket:HTTP WebSocket作用域。一个Bean定义对应于单个WebSocket的生命周期。适用于WebSocket的会话中,保存了一个Map结构的头信息,将用来包裹客户端信息头。
不配置为 singleton,当 scope 为 prototype 时,容器启动不会创建该 bean,在调用getBean方法时才会创建对象
public class MyDatasource { public MyDatasource(){ System.out.println("bean创建,调用无参构造执行"); } public void getConnection(){ System.out.println("创建连接对象执行....."); } public void init(){ System.out.println("init初始化对象执行"); } public void destroy(){ System.out.println("对象销毁执行destroy方法....."); } }
@Test public void test_bean(){ ClassPathXmlApplicationContext context= new ClassPathXmlApplicationContext("spring-datasource.xml"); MyDatasource dataSource = (MyDatasource) context.getBean("dataSource"); // 获取连接对象 dataSource.getConnection(); // 执行销毁操作 context.close(); }
正常关闭容器,才会执行 bean 的配置的 destroy-method 方法。若 bean 的 scope 为 prototype 的,则容器只负责创建和初始化,它并不会被 Spring 容器管理(不需要存起来),由用户自己处理。bean 作用域为 prototype 的即使配置了 destroy-method 也不会被调用。
Spring 创建对象的过程中,将对象依赖属性通过配置设值给该对象。
① setter 注入(属性注入),该类需提供对应的 setter 方法
② 构造器注入:类中必须有无参构造和有参构造
实体类
public class Employee{ private String name; public Employee() {} public Employee(String name) { this.name = name; } public void setName(String name) { this.name = name; } }
测试
public class EmployeeTest { @Test public void test() { User u1 = new User(); // 属性注入 u1.setName("叶凡"); // 构造器注入 User u2 = new User("石昊"); // 注入值可为常量 bean等等 } }
常量指基本数据类型及其包装类,String,BigDecimal等,Bean指的是给对象注入值的是容器中的另外一个对象
① 实体类 – Employee
public class Employee { private String name; private Integer age; private String phone; private Person person; public Person getPerson() { return person; } public void setPerson(Person person) { this.person = person; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } @Override public String toString() { return "Employee{" + "name='" + name + '\'' + ", age=" + age + ", phone='" + phone + '\'' + ", person=" + person + '}'; } }
② 被注入的实体类 – Person
public class Person { @Value("李四") private String name; public Person(){ System.out.println("无参构造"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public void doWork(){ System.out.println(this.name+"要出去玩"); } @Override public String toString() { return "Person{" + "name='" + name + '\'' + '}'; } }
③ 配置文件 – spring-emp.xml
④ 测试
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:spring-emp.xml") public class EmpTest { @Autowired private Employee emp1; @Test public void emp_test(){ System.out.println(emp1); } }
① dao层
// 接口 public interface EmployeeDao { } // 实现类 public class EmployeeDaoImpl implements EmployeeDao{ }
② service层
// 接口 public interface EmployService { } // 实现类 public class EmployServiceImpl implements EmployService{ private EmployeeDao employeeDao; public void setEmployeeDao(EmployeeDao employeeDao) { this.employeeDao = employeeDao; } }
③ xml
① 实体类 – Student
public class Student { private String name; private Long sn; private String phone; private Date birthday; public Student() {} public Student(String name, Long sn, String phone, Date birthday) { this.name = name; this.sn = sn; this.phone = phone; this.birthday = birthday; } public Student(String name, Long sn, String phone) { this.name = name; this.sn = sn; this.phone = phone; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", sn=" + sn + ", phone='" + phone + '\'' + ", birthday=" + birthday + '}'; } }
② 配置文件 – spring-student.xml
③ 测试方法
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:spring-student.xml") public class StudentTest { // 1 2 3 4 依次注入 @Autowired private Student student4; @Test public void student_tes() { System.out.println(student4); } }
主要用于 Spring 框架中,用于完成自动装配。它可以被用于成员变量、方法和构造函数上。
① 可以让 Spring 自动的把属性或字段需要的对象找出来,并注入到属性上或字段上。
② 可以加在字段或者 setter 方法上面。
③ 可以同时注入多个对象,一个对象对应一个注解。
④ 可以注入一些 Spring 内置的重要对象,比如 BeanFactory,ApplicationContext 等。
⑤ 默认情况下 Autowired 注解必须要能找到对应的对象,否则报错。通过 required=false 来避免这个问题:@Autowired(required=false)。(默认为true表示必须找到该对象否则报错)
⑥ Autowired 注解寻找 bean 的方式:
1.首先按照依赖对象的类型找,若找到,就是用 setter 或者字段直接注入。
2.如果在 Spring 上下文中找到多个匹配的类型,再按照名字去找,若没有匹配报错。
3.可以通过使用 @Qualifier(“other(bean的id)”) 标签来规定依赖对象按照 bean 的 id 和 类型的组合方式去找。
实体类
public class Teacher{ @Autowired private Student student ; @Override public String toString() { return "Teacher的学生有[student =" + student + "]"; } }
配置文件
测试类
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:04.anno.xml") public class TeacherTest { @Autowired private Teacher teacher; @Test public void test() { System.out.println(teacher); } }
@Resource 注解用于在 Java 应用程序中实现依赖注入。它是 Java EE 规范的一部分,并被 Spring 框架广泛使用。使用 @Resource 注解,Spring 容器会在运行时查找匹配的 bean,可以将一个对象注入到另一个对象的字段、构造函数或方法中。这个过程通常由 Spring 容器管理,通过扫描带有特定注解的类和方法来实现。
① 可以让 Spring 自动的把属性或字段需要的对象找出来,并注入到属性上或字段上。
② 可以贴在字段或者 setter 方法上面。
③ 可以注入一些 Spring 内置的重要对象,比如 BeanFactory,ApplicationContext 等。
④ Resource 注解必须要能找到对应的对象,否则报错。
⑤ Resource 注解寻找 bean 的方式:
1.首先按照名字去找,如果找到,就使用 setter 或者字段注入。
2.若按照名字找不到,再按照类型去找,但如果找到多个匹配类型,报错。
3.可以直接使用 name 属性指定 bean 的名称(@Resource(name=“”));但若指定的 name,就只能按照 name 去找,若找不到,就不会再按照类型去。
将 Autowired 注解demo 中的 @Autowired 改为 @Resource 即可
在Spring框架中,@Value注解用于给基本类型的属性赋值。它允许从配置文件(如.properties或.yml文件)中读取值,并注入到属性中。@Value注解可以用于方法上或属性上。
public class Student{ @Value("大黄") private String name; @Override public String toString() { return "[name=" + name + "]"; } } // application.properties文件内容 database.url=jdbc:mysql://localhost:3306/mydb database.username=root database.password=secret // value注入 @Value("${database.url}") private String databaseUrl; @Value("${database.username}") private String databaseUsername; @Value("${database.password}") private String databasePassword;
这样,Spring会在启动时从配置文件中读取相应的值,并将其注入到这些属性中。此外,@Value注解也可以用于表达式语言(SpEL)表达式,用于获取bean的属性或调用bean的方法
@Value("${key}") private String valueFromProperty; // 或者 @Value("#{configProperties['key']}") private String valueFromConfig;
将标注的类放入spring容器,交给spring管理,四个注解的功能相同,用于标注不同类型的类(不需再配置xml的bean了)
注解 | 说明 |
---|---|
@Repository | 用于标注数据访问组件,即 DAO 实现类上。 |
@Service | 用于标注业务层实现类上。 |
@Controller | 用于标注控制层类上。 |
@Component | 当不是以上的话,可以使用这个注解进行标注。 |
@Component public class Student{ @Value("大黄") private String name; @Override public String toString() { return "[name=" + name + "]"; } }
注解 | 说明 |
---|---|
@Scope | 贴在类上,标明 bean 的作用域,类似bean标签的scope属性 |
@PostConstruct | 贴在方法上,标明 bean 创建完后调用此方法,类似bean标签的init-method属性 |
@PreDestroy | 贴在方法上,标明容器销毁时调用此方法,类似bean标签的destroy-method属性 |
实体类
@Component @Scope("prototype") public class MyDataSource { public MyDataSource() { System.out.println("bean创建,调用无参构造执行"); } public void getConnection() { System.out.println("创建连接对象执行....."); } @PostConstruct public void init() { System.out.println("init初始化对象执行"); } @PreDestroy public void close() { System.out.println("对象销毁执行destroy方法...."); } }
测试类
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("spring-datasource.xml") public class MyDataSourceTest { @Autowired private MyDataSource dataSource; @Test public void test() { dataSource.getConnection(); } }
上一篇:HNU-数据挖掘-作业1