由于作者水平有限只是对学习过程中遇到的资料进行总结一下,中间可能会有部分错误,如若发现,请在评论区指正,万分感谢。
Spring IoC 是 Spring 框架中用于实现对象之间解耦的核心机制,而 Spring 则是一个基于 IoC 的全面框架,提供了众多的功能模块和工具,帮助开发者更加高效地开发企业级应用。
早期程序员根据配置文件 编写Java代码创建对象 权力指向程序员 但是现在由spring核心容器 在ioc容器中完成实例化反射 权力指向了spring容器。
A-B注入这个过程只需要配置文件后使用ioc容器完成即可
DI 是指将一个对象所需要的依赖关系(其他对象或值)从外部传递给它,而不是让对象自行创建这些依赖关系。换句话说,对象不再负责自己的依赖项的创建和解析,而是由容器负责,容器会在运行时动态地将依赖项注入到对象中。
作用:DI 是一种非常有用的设计模式,它可以帮助开发者更好地管理对象之间的依赖关系,实现对象之间的解耦,从而提高代码的可维护性、可测试性和复用性。在 Spring 框架中,DI 是通过 IoC 容器来实现的,开发者只需要定义对象之间的依赖关系,由容器来负责对象的创建和依赖注入。
这张图片的过程很明确,现在我们来学习一下怎么使用配置文件 创建bean对象,以及依赖注入怎么实现
在 DI 过程中,首先需要实例化被注入的 Bean 对象。这可以通过调用 Bean 的构造函数来创建一个新的实例。如果使用的是无参构造函数,则直接调用构造函数即可实例化对象。如果使用的是有参构造函数,则需要提供构造函数所需的参数值,可以在 XML 配置文件中使用 元素指定参数值。
一旦 Bean 对象实例化完成,接下来就是注入依赖。这可以通过调用 Bean 的 setter 方法或者直接设置 Bean 的字段来完成。在 XML 配置文件中,可以使用 元素来设置属性的值,或者使用 元素来指定构造函数参数的值。
public class Person {
Person() {
}
}
<bean id="person" class="com.code.Person"/>
public class Person {
String name;
Person(String name) {
this.name = name;
}
}
<bean id="person" class="com.code.Person">
<constructor-arg value="person"/>
bean>
public class Person {
String name;
Integer age;
String address;
public Person(String name,Integer age,String address){
this.name = name;
this.age = age;
this.address = address;
}
}
<bean id="person" class="com.example.Person">
<constructor-arg name="name" value="张三"/>
<constructor-arg name="age" value="20"/>
<constructor-arg name="address" ref="address"/>
bean>
在 Spring 中,我们可以使用工厂方法来创建对象。这些工厂方法可以是静态的,也可以是非静态的。
静态工厂方法:静态工厂方法是指定义在一个类中,并使用 static 关键字修饰的工厂方法。在 Spring 中,我们可以使用 元素的 factory-method 属性来指定要调用的静态工厂方法。
public class ShapeFactory {
public static Shape createCircle() {
return new Circle();
}
public static Shape createSquare() {
return new Square();
}
}
<beans>
<bean id="circle" class="com.example.Circle" factory-method="createCircle"/>
<bean id="square" class="com.example.Square" factory-method="createSquare"/>
beans>
public class Person {
private static Person person = new Person();
private Person (){}
public static Person creatPerson(){
return person;
}
}
<bean id="person" class="com.code.Person" factory-method="creatPerson"/>
相当于直接进行调用了,返回的对象是唯一的,减少创建 保证线程安全 类似于饿汉,单例模式
public interface ShapeFactory {
Shape createShape();
}
public class CircleFactory implements ShapeFactory {
public Shape createShape() {
return new Circle();
}
}
public class SquareFactory implements ShapeFactory {
public Shape createShape() {
return new Square();
}
}
<beans>
<bean id="circleFactory" class="com.example.CircleFactory"/>
<bean id="squareFactory" class="com.example.SquareFactory"/>
<bean id="circle" factory-bean="circleFactory" factory-method="createShape"/>
<bean id="square" factory-bean="squareFactory" factory-method="createShape"/>
beans>
多个参数的有参构造写法
class Address{ }
public class Person {
private Address address;
private Integer age;
public Person(Integer age){
this.age = age;
}
}
<bean id="person" class="com.example.Person">
<constructor-arg name="age" value="20"/>
<property name="address">
<bean class="com.example.Address"/>
property>
bean>
先根据配置创建ioc容器 从容器中获取配置的bean对象 使用对象进行调用
获取容器有三种方法,你可以根绝需求选择对应的容器,选择和合适的方法创建和使用
@Test
public void getBeanFromIoc() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("demo-01.xml");
// 查找是根据beanid进行的查找
// 如果ioc容器存在多个同类型的bean会出现问题
// ioc的配置一定是实现类 创建的bean是实例化 可以使用多态 但是 指向的配置文件一定是接口的实现类
HelloWorld helloWorld = applicationContext.getBean("helloWorld", HelloWorld.class);
helloWorld.doWork();
}
FactoryBean是Spring框架中的一个接口,它允许开发人员定制化地创建和配置bean实例。通常情况下,使用工厂模式创建bean时,需要编写一个工厂类来负责bean的创建和初始化。而使用FactoryBean接口可以将这些工厂类封装起来,使得在配置Spring容器时更加方便。
实现FactoryBean接口的类需要提供自定义的逻辑来创建bean实例,并且该类本身也会成为Spring容器中的一个bean。通过FactoryBean可以实现更加灵活的bean创建和初始化过程,例如根据不同条件创建不同的实例,或者对属性进行特殊处理。
当Spring容器遇到实现了FactoryBean接口的bean定义时,它会调用FactoryBean的方法来获取实际的bean实例,而不是直接返回FactoryBean本身。这样的设计允许开发人员在创建bean时进行更多的定制化操作,从而满足复杂的业务需求。
import org.springframework.beans.factory.FactoryBean;
public class MyBeanFactory implements FactoryBean<MyBean> {
private String someProperty;
// 设置属性
public void setSomeProperty(String someProperty) {
this.someProperty = someProperty;
}
// 返回bean实例
@Override
public MyBean getObject() throws Exception {
MyBean myBean = new MyBean();
myBean.setSomeProperty(someProperty);
return myBean;
}
// 返回bean的类型
@Override
public Class<?> getObjectType() {
return MyBean.class;
}
// 是否是单例
@Override
public boolean isSingleton() {
return true;
}
}
<bean id="myBean" class="com.example.MyBeanFactory">
<property name="someProperty" value="someValue"/>
bean>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>6.0.6version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.25version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.2.8version>
dependency>
<dependency>
<groupId>jakarta.annotationgroupId>
<artifactId>jakarta.annotation-apiartifactId>
<version>2.1.1version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>6.0.6version>
dependency>
dependencies>
配置这部分内容按照正常的maven配置即可
我们采取接口和实现类的形式编写这个模块的内容
package com.ssmlearn.dao;
import com.ssmlearn.pojo.Student;
import java.util.List;
public interface StudentDemo {
List<Student> querryAll();
}
package com.ssmlearn.dao;
import com.ssmlearn.pojo.Student;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
public class StudentDaoImpl implements StudentDemo{
private JdbcTemplate jdbcTemplate;
// 这个是提供的set方法
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
// 这个是实现的方法
@Override
public List<Student> querryAll() {
String sql ="select * from students";
List<Student> students = jdbcTemplate.query(sql,new BeanPropertyRowMapper<>(Student.class));
System.out.println("Dao层内容"+students);
return students;
}
}
package com.ssmlearn.service;
import com.ssmlearn.pojo.Student;
import java.util.List;
public interface FindAll {
public List<Student> findAll();
}
package com.ssmlearn.service.iml;
import com.ssmlearn.dao.StudentDaoImpl;
import com.ssmlearn.pojo.Student;
import com.ssmlearn.service.FindAll;
import java.util.List;
public class FindAllimpl implements FindAll {
private StudentDaoImpl studentDao;
// setter方法
public void setStudentDao(StudentDaoImpl studentDao) {
this.studentDao = studentDao;
}
@Override
public List<Student> findAll() {
List<Student> students = studentDao.querryAll();
System.out.println("Service"+students);
return students;
}
}
package com.ssmlearn.constroller;
import com.ssmlearn.pojo.Student;
import com.ssmlearn.service.iml.FindAllimpl;
import java.util.List;
public class StudentConstroller {
FindAllimpl findAllimpl;
public void setFindAllimpl(FindAllimpl findAllimpl) {
this.findAllimpl = findAllimpl;
}
public void findAll(){
List<Student> all = findAllimpl.findAll();
System.out.println("最终结果"+all);
}
}
这个主要是跟前端交互的内容,这里直接创建services层的代码,然后进行调用。
完成这部分内容之后,我们需要进行Di的配置
<context:property-placeholder location="classpath:jdbcTemplate.properties"/>
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="${atguigu.url}"/>
<property name="driverClassName" value="${atguigu.driver}"/>
<property name="username" value="${atguigu.username}"/>
<property name="password" value="${atguigu.password}"/>
bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="druidDataSource"/>
bean>
<bean id="studentDao" class="com.ssmlearn.dao.StudentDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
bean>
<bean id="findAllimpl" class="com.ssmlearn.service.iml.FindAllimpl">
<property name="studentDao" ref="studentDao">property>
bean>
<bean id="studentConstroller" class="com.ssmlearn.constroller.StudentConstroller">
<property name="findAllimpl" ref="findAllimpl"/>
bean>
完成配置信息之后,我们需要进行测试,选取单元测试,使用注解的形式进行测试内容
@Test
void testIoc(){
// 1.创建一个ioc容器
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spirng-ioc-02.xml");
// 2.获取一个控制层的对象实例 这个是通过ioc根绝配置自动完成的
StudentConstroller bean = applicationContext.getBean(StudentConstroller.class);
// 3.调用bean对象的方法
bean.findAll();
// 4.释放
applicationContext.close();
}