前言:什么是Spring框架?
Srping框架是一款基于JavaEE应用程序开发的开源的、轻量级的开发框架,以IOC(inverse of control)控制反转 和AOP(Aspect oriented programming)面向切面编程为内核,为java应用程序提供了组件管理服务,用于组件间的解耦,其主要目的是为了简化企业级应用程序的开发,促进低耦合,可扩展,可维护的代码。
什么是IOC?
IOC(inverse of control)控制反转:其核心理念是将对象的控制权交给Spring框架管理,由Spring框架根据配置文件和注解统一管理Bean对象的创建和对象之间的依赖关系,是Spring框架的核心思想之一,主要作用是降低程序之间的耦合性。
- 控制 :指的是对象创建(实例化、管理)的权力
- 反转 :控制权交给外部环境(Spring框架、IoC容器)
什么是IOC容器
SpringIOC容器是实现IOC设计模式的一个重要组件,用来创建Bean对象并管理Bean对象的生命周期,并根据配置文件和注解,管理容器中的每一个对象和对象间的依赖关系,属于Spring中的Core核心板块。
IOC容器内部是一个ConCurrentHashMap来维护了一个Beandefinition对象,该对象用来封装Spring对一个bean的所有配置信息(类名、属性、构造方法、依赖等)。
什么是Spring DI
Dependecy in 依赖注入:是SrpingIOC控制反转设计模式的一个具体实现,用于实现和维护对象间的依赖关系,就是在程序运行过程中,将一个对象依赖的其他对象注入到这个对象中,从而实现注入的思想理念。
Spring中的Bean
简单来说,Bean就是IOC容器管理的对象
Bean就是Spring容器管理的java对象
通过配置文件或者注解,告诉IOC容器需要帮助管理哪些对象
一.使用springIOC容器管理javaBean步骤:
- 创建JavaBean
- 将类注入spring容器
配置语法:
<bean id="唯一标识" class="类的完全限定名称"></bean>
例如
<bean id="student" class="com.apesource.pojo.Student"></bean>
-
测试:
3.1加载spring主配置文件获取核心对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(“beans.xml”);
3.2让spring以解耦的方式进行对象的实例化返回用户
applicationContext.getBean(“id”);
二.ID依赖注入的三个阶段:
1.基于XMl文件的依赖注入
DI实现方式:
set注入=通过set方法维护对象之间的依赖关系
- 给属性提供set方法
- 在bean标签内部开启配置
配置位置:此位置
配置语法:<property 属性名=“属性值”>- 配置属性:
name======》属性名称
value=====》属性值
ref=======》属性值的引用
<bean id="student" class="com.apesource.pojo.Student">
<property name="stuName" value="张三丰"></property>
<property name="stuHobby" value="RAP"></property>
<property name="stuAge" value="100"></property> </bean>
构造注入=通过构造方法维护对象之间的依赖关系
类中需要提供一个对应参数列表的构造函数;
在bean标签内部开启配置
配置位置:此位置
配置语法:<constructor-arg 属性名=“属性值” >属性:
index:指定参数在构造函数参数列表的索引位置
type:指定参数在构造函数中的数据类型
name:指定参数在构造函数中的名称 用这个找给谁赋值
=上面三个都是找给谁赋值,下面两个指的是赋什么值的========
value:它能赋的值是基本数据类型和String 类型
ref:它能赋的值是其他 bean 类型,也就是说,必须得是在配置文件中配置过的 bean
<!--注入student类方式1 name-->
<bean id="student1" class="com.apesource.pojo.Student">
<constructor-arg name="stuName" value="GGBond"></constructor-arg>
<constructor-arg name="stuAge" value="8"></constructor-arg>
</bean>
<!--注入student类方式2 index-->
<bean id="student2" class="com.apesource.pojo.Student">
<constructor-arg index="0" value="GGBond"></constructor-arg>
<constructor-arg index="1" value="8"></constructor-arg>
</bean>
<!--注入student类方式3 type-->
<bean id="student3" class="com.apesource.pojo.Student">
<constructor-arg type="java.lang.String" value="GGBond"></constructor-arg>
<constructor-arg type="int" value="8"></constructor-arg>
</bean>
2.基于annonation注解+xml文件的依赖注入
将基于xml标签注入类的形式更换成了注解的形式:
<bean id="" class="" init-method="" destroy-method="" scope="" autowire="">
<property></property>
<constructor-arg></constructor-arg>
</bean>
替换为一些更加方便的注解+xml文件的形式:
第一类:注入类
1.@Component:将注解所修饰的类注入spring容器
2.@Repository 注入数据访问层
3.@Service 注入业务层
4.@Controller 注入控制层
语法:@Component(value = “id”)
如果省略value="id"默认注入的id为类的名称且首字母小写
@Controller
public class UserControllerImpl implements UserController {
......
}
注意:不可以单独使用,需要配置xml文件
<context:component-scan base-package=“”></context:component-scan>
<!--@Component需要的包扫描-->
<context:component-scan base-package="com.XXXXXX"></context:component-scan>
第二类:注入数据
1.@Value():向属性注入基本类型与String
语法:@Value(“数据”) @Value(“${key}”)
虽然使用了注解的方式注入值,但还是硬编码,不推荐
@Value("杨老师")
private String Name;
@Value("18")
private int age;
@Value("${msg1}")//el表达式
private String stuname;
@Value("${msg2}")
private int stuage;
注意:不可以单独使用,需要配置xml文件
<context:property-placeholder location=“”></context:property-placeholder>
<!--@value需要的资源位置-->
<context:property-placeholder location="msg.properties"></context:property-placeholder>
2.@Autowired():自动装配属性
含义:通过“set”方法【set方法可以省略】,按照“类型”自动装配,如果类型冲突则按照"名称"装配
@Autowired
UserDao userDao;
注意:@Autowired()注解默认按照类型进行自动装备
1.按类型装配如果冲突切换为名称装配
2.按类型装配如果冲突切换为名称装配,如果名称也没有则会抛异常
NoUniqueBeanDefinitionException
3.按类型装配没一个匹配
NoSuchBeanDefinitionException
第三类:其他注解
- @Primary:在类型装配冲突的情况下,此注解所修饰的类作为首选项,作用于类,不能单独用
@Primary
public class UserCopyDaoImpl implements UserDao{
public void save(){
System.out.println("dao层");
}
}
- @Qualifier按照名称装配,作用于属性,不能单独用
@Autowired
@Qualifier(value = "userDaoImpl")
UserDao userDao;
- @Resource:按照名称装配,作用于属性,单独用
@Resource(name = "userDaoImpl")
UserDao userDao;
- @Scope:作用域,作用于类,不能单独用
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class UserServiceImpl implements UserService
- @PreDestroy 含义:替换destory-method,作用于方法,单独用
@PreDestroy
public void dodestory(){
System.out.println("属性销毁");
}
6.@PostConstruct:替换init-method,作用于方法,单独用
@PostConstruct
public void doinit(){
System.out.println("属性初始化");
}
3.基于annonation注解+javaConfig配置类的依赖注入
在Spring3.0版本之后,Spring为我们提供了全新的配置方案,就是annonation注解+javaConfig配置类的形式。在之前的xml配置文件中,其底层实现逻辑也是根据xml的解析器对象,将xml配置文件转换成配置类的形式来帮我们实现配置,而javaConfig配置类则能跳过解析的步骤,更加方便的为程序进行配置。
在javaConfig3.0版中比较重要的注解有:
- @Configuration:用这个注解修饰的类才是配置类,替换了原来的xml配置文件
- @ComponentScan():替代ComponentScan标签做注入类注解需要的包扫描
- @PropertySource():替代property-placeholder标签做资源文件加载
- @import():导入其他配置类
@Configuration
@ComponentScan(basePackages = {"com.apesource"})
@Import(DataSourceConfig.class)
public class SpringConfig {
}
@Configuration
@PropertySource(value = "classpath:jdbc.properties")
public class DataSourceConfig {
}
- @Bean: 注入类的新注解,作用于方法上,单独使用,无需扫描,可以注入java核心类库中的类
方法返回值为class,方法参数名为id
@Configuration
public class SpringConfig {
//向容器中注入id为creatStu且class为Studetn的类
@Bean
public Student creatStu(){
return new Student();
}
//向容器中注入id为stu且class为Studetn的类
@Bean(name = "stu")
public Student creatStus(){
return new Student();
}
//向容器中注入Java核心类库中的类
@Bean
public Date date(){
return new Date();
}
}
使用@Bean注解也可以在方法中实现依赖注入,通过有参构造方法传参来实现:
public class UserControllerImpl implements UserController {
UserService userService;
public UserControllerImpl(UserService userService) {
this.userService = userService;
.....
}
}
......
@Configuration
public class SpringConfig {
//方法1
@Bean
public UserDao userDao(){
return new UserDaoImpl();
}
@Bean
public UserService userService(){
return new UserServiceImpl(userDao());
}
@Bean
public UserController userController(){
return new UserControllerImpl(userService());
}
//方法2
@Bean
public UserDao userDao(){
return new UserDaoImpl();
}
@Bean
public UserService userService(/*@Autowired*/UserDao dao){
return new UserServiceImpl(dao);
}
@Bean
public UserController userController(UserService service){
return new UserControllerImpl(service);
}
}
注意:
ClassPathXmlApplicationContext()实现类是通过类路径下的配置文件来获取容器对象
AnnotationConfigApplicationContext()实现类是通过加载配置类来获取容器对象
总结
- 将所有的javaBean注入spring容器进行“解耦”管理,spring万物皆为bean;
- Spring第一大核心思想IOC控制反转 DI依赖注入
- spring配置方案经历了三代变化:
xml====>annonation+xml===>annonation+javaConfig配置类