Spring框架入门
- 简介
- 开发环境
- 入门案列
- Spring bean的定义
- 常用属性
- Spring IOC (控制反转)
- 简介
- 控制反转(IoC)
- 案例
- 依赖注入(DI)
- IoC 容器的两种实现
- ApplicationContext
- BeanFactory
- Spring Bean属性注入
- 构造函数注入
- setter 注入
- Spring自动装配
- 注解开发
- 配置
- 定义bean
简介
Spring是一个流行的Java应用程序框架,它简化了Java开发,提供了广泛的功能和组件,使开发人员能够更快速、更高效地创建企业级应用程序。在入门Spring之前,我们需要具备Java基础知识和javaWeb知识。
开发环境
idea,jdk17
入门案列
在项目中创建一个类HelloWorld类
里面除了定义了一个方法什么都没干
package com.example.demo;
public class HelloWorld {
public void sayHello(){
System.out.println("hello");
};
}
在resources目录下新建一个配置文件application.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="helloWorld" class="com.example.demo.HelloWorld"/>
</beans>
新建一个Application.java类
package com.example.demo;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloWorld helloWorld =(HelloWorld) app.getBean("helloWorld");
helloWorld.sayHello();
}
}
然后在application.java中右键运行就可以看到输出结果hello
Spring bean的定义
由 Spring IoC 容器管理的对象称为 Bean,Bean 根据 Spring 配置文件中的信息创建
<bean id="helloWorld" class="com.example.demo.HelloWorld"/>
常用属性
id Bean 的唯一标识符,Spring IoC 容器对 Bean 的配置和管理都通过该属性完成
constructor-arg属性,bean 元素的子元素,我们可以通过该元素,将构造参数传入,以实现 Bean 的实例化。该元素的 index 属性指定构造参数的序号(从 0 开始),type 属性指定构造参数的类型。
property属性bean元素的子元素,用于调用 Bean 实例中的 setter 方法对属性进行赋值,从而完成属性的注入。该元素的 name 属性用于指定 Bean 实例中相应的属性名。
ref property和 constructor-arg 等元素的子元索,用于指定对某个 Bean 实例的引用,即 元素中的 id 或 name 属性。
value property 和 constractor-arg 等元素的子元素,用于直接指定一个常量值。
scope 表示 Bean 的作用域,属性值可以为 singleton(单例)、prototype(原型)、request、session 和 global Session。默认值是 singleton。
init-method 容器加载 Bean 时调用该方法,类似于 Servlet 中的 init() 方法
set 用于封装 Set 类型的属性注入。
map 用于封装 Map 类型的属性注入。
list 用于封装 List 或数组类型的属性注入。
Spring IOC (控制反转)
简介
IoC 是 Inversion of Control
的简写,译为“控制反转”,它不是一门技术,而是一种设计思想,是一个重要的面向对象编程法则,能够指导我们如何设计出松耦合、更优良的程序。Spring 通过 IoC 容器来管理所有 Java 对象的实例化和初始化,控制对象与对象之间的依赖关系。我们将由 IoC 容器管理的
Java 对象称为 Spring Bean,它与使用关键字 new 创建的 Java 对象没有任何区别。IoC 容器是 Spring 框架中最重要的核心组件之一,它贯穿了 Spring 从诞生到成长的整个过程。
控制反转(IoC)
1.传统java开发中,service层想要调用dao层的属性或方法,只能通过new一个新的对象来实现,但现在Spring为我们提出了新的解决思路
2.我们只需要在配置文件中对java类进行配置或通过注解的方式对对象进行标注,在Spring启动时,就会启用IoC容器帮我们管理这些对象,这些被 IoC 容器创建并管理的对象被称为 Spring Bean。
3.当我们需要使用这些bean时,我们只需要用ApplicationContext的getBean方法就可以拿到我么需要的bean,而不需要new
下面是一个简单的案例
案例
定义BookDao和BookService接口和实现类
下面是实现类的具体内容
package com.example.demo.dao.impl;
import com.example.demo.dao.BookDao;
public class BookDaoImpl implements BookDao {
@Override
public void save() {
System.out.println("BookDaoImpl");
}
}
package com.example.demo.service.impl;
import com.example.demo.dao.BookDao;
import com.example.demo.dao.impl.BookDaoImpl;
import com.example.demo.service.BookService;
public class BookServiceImpl implements BookService {
private BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
@Override
public void save() {
this.bookDao.save();
}
}
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="bookDao" class="com.example.demo.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.example.demo.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>
</beans>
Application 启动类
package com.example.demo;
import com.example.demo.dao.BookDao;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao =(BookDao) app.getBean("bookDao");
bookDao.save();
}
}
右键运行Application方法即可输出BookDao中的内容
依赖注入(DI)
依赖注入(Denpendency Injection,简写为 DI)在面向对象中,对象和对象之间是存在一种叫做“依赖”的关系。简单来说,依赖关系就是在一个对象中需要用到另外一个对象,即对象中存在一个属性,该属性是另外一个类的对象。
在对象创建过程中,Spring 会自动根据依赖关系,将它依赖的对象注入到当前对象中,这就是所谓的“依赖注入”。依赖注入本质上是 Spring Bean 属性注入的一种,只不过这个属性是一个对象属性而已。
在上面的案例中我们配置了以下内容
<bean id="bookDao" class="com.example.demo.dao.impl.BookDaoImpl"/>
<bean id="bookService" class="com.example.demo.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/>
</bean>
我们使用property元素来完成依赖注入,我们没有使用构造函数注入,而是在xml中使用元素来注入bookDao。name属性来指定需要注入的属性名,使用ref属性来指定需要注入的对象。这样,我们就完成了依赖注入的操作。
IoC 容器的两种实现
ApplicationContext
ApplicationContext是 BeanFactory 接口的子接口,是对 BeanFactory 的扩展,我们上面的案例中就使用这种方式实现
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
BeanFactory
BeanFactory 采用懒加载(lazy-load)机制,容器在加载配置文件时并不会立刻创建 Java 对象,只有程序中获取(使用)这个对对象时才会创建。
BeanFactory app = new ClassPathXmlApplicationContext("applicationContext.xml");
Spring Bean属性注入
构造函数注入
假设有一个名为 Person 的 Java 类,它有两个属性:name 和 age,并且有一个构造器可以接受这两个属性的值
package com.example.demo;
public class Person {
public String name;
public int age;
public Person(){ //无参构造器
}
public Person(String name, int age) { //提供有参构造器
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
现在我们想在 Spring 应用程序中使用这个 Person 类,同时使用构造器注入来注入属性值。我们可以在 Spring 配置文件中添加如下的 bean 配置:
<bean id="person" class="com.example.demo.Person">
<constructor-arg value="张三" />
<constructor-arg value="20" />
</bean>
上面的配置定义了一个名为 person 的 bean,它的类型是 Person。在 constructor-arg 元素中,我们指定了 Person 类的构造器需要接受两个参数,分别是 “张三” 和 30,用来初始化 Person 对象的 name 和 age 属性
当我们在应用程序中需要使用 Person 对象时,可以像下面这样注入它:
package com.example.demo.service;
import com.example.demo.Person;
public class PersonService {
private Person person;
public PersonService(Person person) {
this.person = person;
}
}
在Application中测试有没有注入成功
package com.example.demo;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
// ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
BeanFactory app = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = (Person) app.getBean("person");
System.out.println(person.name);
System.out.println(person.age);
}
}
控制台输出:张三 30
setter 注入
setter注入我们通过修改上面的案例来实现
person类文件可以不做任何修改
Spring配置文件中的配置修改如下
<bean id="person" class="com.example.Person">
<property name="name" value="张三" />
<property name="age" value="20" />
</bean>
在上面的配置中,我们使用 property 元素来设置 Person 对象的 name 和 age 属性的值。
最后,在需要使用 Person 对象的类中,我们可以使用 setter 注入的方式将 person 属性注入进去:
package com.example.demo.service;
import com.example.demo.Person;
public class PersonService {
private Person person;
public void setPerson(Person person) {
this.person = person;
}
}
Application文件中的代码不需要改
右键运行输出结果: 张三 20
Spring自动装配
//bookDao的定义
<bean id="bookDao" class="com.example.demo.dao.impl.BookDaoImpl"/>
//bookService的定义
<bean id="bookService" class="com.example.demo.service.impl.BookServiceImpl">
//把bookDao和bookService联系在一起
<property name="bookDao" ref="bookDao"/>
</bean>
在bookService的实现类中我们只需要提供setter方法即可
private BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
在上面的代码中,我们定义了一个名为 bookDao的属性,并提供了一个名为setBookDao 的 setter 方法。这个 setter 方法会被 Spring 自动调用,从而将 bookDao bean 注入到 bookService bean 中。
注解开发
Spring3.0开启了纯注解开发,使用java类代替了配置文件
配置
package com.example.demo;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration //申明该类为一个配置类
@ComponentScan("com.example.demo") //扫描bean设置扫描路径
public class SpringConfig {
}
这段代码就替代了xml中的配置
在加载配置容器初始化时要修改成以下内容
ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfig.class);
定义bean
@Component //它表示一个通用的 Spring 组件,可以用在任何层次上(如 DAO、Service、Controller 等)
@Service // 通常用来注解业务层(Service 层)的组件,用于标识一个 Bean 是服务层组件。
@Controller //通常用来注解控制层(Controller 层)的组件,用于标识一个 Bean 是 Web 控制器组件
@Repository //通常用来注解数据访问层(DAO 层)的组件,用于标识一个 Bean 是数据访问组件
@Autowired //自动装配
以上为最基本最常用的bean
有了以上基础我们可以完成以下案例
新建一个SpringConfig.class 配置类
package com.example.demo;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration //申明该类为一个配置类
@ComponentScan("com.example.demo") //扫描bean
public class SpringConfig {
}
新建一个UserDao类,用@Repository声明它为一个spring的bean,后面小括号中设置它的名字
package com.example.demo.dao.impl;
import org.springframework.stereotype.Repository;
@Repository("userDao")
public class UserDao {
public void getUser(){
System.out.println("getUser方法");
}
}
在声明一个UserService类,声明了它是一个service层的bean,并且还使用Autowired自动装配
package com.example.demo.service;
import com.example.demo.dao.impl.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
public UserDao userDao;
@Autowired
public UserService(UserDao userDao) {
this.userDao = userDao;
}
}
最后在Application中测试
package com.example.demo;
import com.example.demo.dao.impl.UserDao;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ApplicationContext app = new AnnotationConfigApplicationContext(SpringConfig.class);
UserDao userDao = (UserDao) app.getBean("userDao");
userDao.getUser();
}
}
控制台输出 :getUser方法
写不动了,就先写到这里吧!