目录
ApplicationContext VS BeanFactory
这篇博客我将介绍Spring项目的创建和Bean对象的注入和使用
创建Spring项目
步骤
我来详细介绍创建过程
1)使用Maven的方式创建Spring项目
2)添加Spring依赖
在pom.xml中添加依赖(spring-context/spring-beans)
3)创建启动类
在java文件夹中创建启动类包含main方法即可
存Bean对象
我们创建完Spring项目就可以开始存Bean对象了,Bean就是Java中普通的对象
1.创建Bean对象
public class User {
//Bean对象
public void fun() {
System.out.println("hello world");
}
}
2.将Bean注册到Spring中
在resources中创建Spring-config.xml配置并使用
Spring配置文件内容固定只需要添加要注册的Bean,具体操作是在<Beans>中添加如下配置
<?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">
<!-- 注册一个对象到spring中 -->
<bean class="com.User" id="user"></bean>
</beans>
在上面代码中可以看到我已经注册一个对象到Spring中了,其中有两个参数 class表示要注册对象的位置(包名+类名),id表示标识(一般为类名小驼峰)作为取对象使用
取Bean对象并使用
步骤
1.先得到Spring上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
注意:参数中的内容要和创建的xml名称一一对应
2.从Spring中获取Bean对象
User user = (User) context.getBean("user");
context.getBean()的方法重载有很多这里先介绍最简单的根据Sting [bean id]获取Bean,通过之前在xml中注册的id作为getBean的参数来从Spring中获取bean对象
根据Class参数获取Bean [根据类型]
User user1= context.getBean(User.class);
根据String [bean id]和Class获取bean
User user2=context.getBean("user",User.class);
3.使用Bean
user.fun();//使用Bean对象
ApplicationContext VS BeanFactory
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
BeanFactory context= new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
共同点:都是用来获取Spring上下文对象
不同点:
1.继承关系和功能:ApplicationContext属于BeanFactory子类,ApplicationContext拥有独特的特性, 还添加了对国际化支持、资源访问支持、以及事件传播等方面的支持
2.性能方面来说:ApplicationContext 是⼀次性加载并初始化所有的 Bean 对象,而BeanFactory 是需要那个才去加载那个,因此更加轻量
在上面的博客内容中我们已经可以实现Spring的读取和存储对象的功能了,但是感觉并不高效,所以接下来我将介绍Spring更简单的读取和存储对象就是通过使用注解
存储Bean对象(更简单)
1.前置工作
在存储Bean对象前我们先需要在xml中配置⼀下存储对象的扫描包路径,只有被配置的包下的所有类,添加了注解才能被正确的识别并保存到 Spring 中
2.使用注解存储对象
要将对象存储到Spring中有两种注解类型可以实现
使用类注解
1.@Controller 控制器 验证前端传递的参数
2.@Service 服务层 服务调用的编排和汇总
3.@Repository 仓库(数据仓库) 直接操作数据库
4.@Componet 组件 通用化的工具类
5.@Configuration 配置 项目的所有配置
在上面的代码片段中我们会发现几个问题,注解都能完成相同的任务为什么要有这么多的类注解,它们之间的关系怎样的,读取bean为什么使用小驼峰,接下来我会一一介绍
1)为什么这么多的类注解
这么多的类注解就是让程序员在看到类注解之后能够知道当前类的用途,进而提高代码的可读性和可阅读性
2)类注解之间的关系
我们可以通过源码来看看 @Controller / @Service / @Repository / @Configuration 等注解都是基于@Component,它们的作用是将Bean对象存储到Spring中
3)Bean的命名规范
默认情况:我们通常命名Bean是使用大驼峰命名,但是在读取Bean时又要将首字母小写来获取
特殊情况:但是在有开头两个字母大写的时候,在读取时却要使用定义的类名才能找到
原因是什么呢?我们就需要了解一下Bean的命名规则了
方法注解@Bean
使用方法注解将Bean存储到Spring中,在使用类注解时我们是将类注解添加到类上的,使用方法注解则是需要将@Bean添加到方法上并配合五大类注解使用,本质是为了提升效率
@Bean注解方法名(命名规则)
在上面的代码中我们可以看到在getBean中我们使用方法名来获取Bean对象,和五大类注解的命名方式并不相同,因为在相同类中可能有多个返回相同类型的方法,所以选择使用方法名是更好的选择,但是在不同类中也会出现同名的方法这就会造成使用的麻烦,所以就需要重命名Bean
此时只能获取到唯一的结果,我们就可以使用重命名Bean来获取所需要的Bean了
@Bean重命名的格式
@Bean("student_user1")
@Bean(name = "stu_user1")
@Bean(value = "stu_user2")
@Bean(name={"student_user1","stu_user1"})
注意事项
1.@Bean必须配合五大类注解一起使用(不然注入不进去)
2.@Bean方法注解只能使用在无参的方法上(Spring 初始化存储时,没法提供相应的参数)
3@Bean重命名之后使用方法名就不能获取Bean对象了
获取Bean对象(对象装配)
获取Bean对象也叫做对象装配,是将对象取出来放到某个类中有时候也叫对象注入
1.属性注入
优点
属性注入实现简单,使用简单,只需要给变量上添加一个注解@Autowired就可以在不new对象的情况下,直接获得注入对象了
缺点
①不能注入final修饰的变量
②通用性弱只适用IoC框架(容器)
③更容易违背单一设计原则
④idea不建议使用
2.setter注入
在设置 set 方法的时候需要加上 @Autowired 注解
优点
①符合单一设计原则(一个setter只针对一个对象)
缺点
①不能注入final修饰的变量
②注入对象可能被改变(setter方法可能被多次调用,存在篡改的风险)
3.构造方法注入
当当前类只有一个构造方法时此时@Autowrired注解可以省略,言外之意多个构造方法必须使用@Autowired注解指定构造方法
优点
①可以注入不可变对象(final修饰的对象)
为什么构造方法注入就可以解决呢,这里是遵循了Java的规范也就是final的用法:①创建时直接赋值②在构造方法中进行赋值,构造方法注入就符合②的方式了而前两种注入方式无法满足
②注入对象不会被修改
构造方法在对象创建时只会执行一次因此注入的对象不存在被随意修改的情况
③依赖的对象在使用前一定会完全初始化
因为依赖的类是在构造方法中执行的,而构造方法是在类创建之初就会执行的方法
④通用性更好
因为构造方法是Java(JDK)支持的,所以更换任何框架都是适用的
@Resource注解
我们除了可以使用@Autowired进行注入还可以使用@Resource进行对象注入
注意事项
@Resource注解在属性注入和stetter注入是支持的但是构造方法注入不支持
@Resource注解有更多的方法,在特殊情况下有更好的效果
在上面的代码片段中我们看到可以修改@Resource的name方法来获取指定的Bean对象,@Autowired就没有相同方式获取Bean对象了,但是可以通过@Qualifier注解处理同一类型多个Bean对象获取问题
通过@AutoWired+@Qualifier的value方法就可以解决了