Chapter 01 Spring基础及组件使用
Section 01 - Spring是什么?
Spring致力于J2EE的各种解决方案,而不仅仅专注于某一层解决方案。可以说Spring是企业应用开发的“一站式”选择, Spring贯穿于表现层、业务层、持久层,然而Spring并不想取代那些已经有的框架,而是以高度的开放性,与这些已有的框架进行整合。
Spring早期使用最多的是IoC容器及DI依赖注入,通过在application.xml文件中配置bean标签,将项目中的组件或对象交给IoC容器管理,当初始化IoC容器时,Bean会被创建或者实例化,这就导致一个巨大项目中需要配置非常多的bean标签,维护起来非常繁琐。
Spring 核心体系
- Spring Core:即,Spring核心,它是框架最基础的部分,提供IOC和依赖注入特性
- Spring Context:即,Spring上下文容器,它是BeanFactory功能加强的一个子接口
- Spring Web:它提供Web应用开发的支持
- Spring MVC:它针对Web应用中MVC思想的实现
- Spring DAO:提供对JDBC抽象层,简化了JDBC编码,同时,编码更具有健壮性。
- Spring ORM:它支持用于流行的ORM框架的整合,比如:Spring + Hibernate、Spring + iBatis、Spring + JDO的整合等等。
Spring常用组件
Section 02 - XML与注解注册Bean
创建maven项目, 添加依赖 添加entity包,新增实体类Person
public class Person { private String name; private Integer age; //省略getter/setter/toString }
xml配置方式注册Bean
在resource目录下新建beans.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="person" class="com.citi.entity.Person"> <property name="name" value="Peter"></property> <property name="age" value="18"></property> </bean> </beans>
在test pacakge下新建SingleBeanContainerTest测试类,加入main方法,调用getBeanByXml()方法,测试从容器中获取bean
public static void getBeanByXml(){ ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml"); Person person = (Person) context.getBean("person"); System.out.println(person); }
控制台打印
使用注解方式注册Bean新建config包,增加配置类BeanConfig
@Configuration public class BeanConfig { @Bean public Person person(){ Person person = new Person(); person.setName("Stark"); person.setAge(40); return person; } } 复制代码
@Configuration:标识为一个配置类,等同于配置文件 @Bean:给容器注册一个Bean,类型为返回值的类型,bean id为返回名 SingleBeanContainerTest中新增方法,在main方法中执行
public static void getBeanByAnno(){ ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class); Person person = (Person) context.getBean("person"); System.out.println(person); String[] beanNamesForType = context.getBeanNamesForType(Person.class); for (String s : beanNamesForType) { System.out.println("Bean id:" + s); } } 复制代码
控制台输出
修改BeanConfig中@Bean注解下的方法的方法名为stark
@Bean public Person stark(){ Person person = new Person(); person.setName("Stark"); person.setAge(40); return person; } 复制代码
再次运行SingleBeanContainerTest的mian方法,控制台报错No bean named 'person' available
这是因为代码中获取的bean的id为person,而配置了中@Bean注解下的方法名也就是bean的id为stark,所以出现报错,更改getBean("person")为getBean("stark"),再次执行,获取成功
除了修改@Bean注解下的方法名来定义Bean的id,也可以通过@Bean("thor")的方式来定义Bean的名称
IoC容器的数据结果为Map,注册Bean是就是往Map里面添加数据,使用put("key",value),key为Bean的id,value就是对象,
Section 03 - XML与注解批量注册Bean
@CompponmentScan 代替@Bean 分别新增controller,service,dao三个package,并增加响应的类,通过@Controller,@Service,@Repository三个注解将三个类声明为Bean
@Controller public class PersonController { } 复制代码
@Service public class PersonService { } 复制代码
@Repository public class PersonDao { } 复制代码
修改BeanConfig,增加@ComponentScan注解,将com.citi包下面的所有Bean都扫描到BeanConfig这个配置类中,就相当于XML配置文件中有许多bean标签,好处是不用一个个写bean标签,通过一个注解可以扫描所有的Bean
@Configuration @ComponentScan(basePackages = "com.citi") public class BeanConfig { } 复制代码
测试IoC容器是否实例化扫描到的Bean,新增一个ComponentScanTest测试类
public class ComponentScanTest { @Test public void getBeansByScan(){ ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class); String[] beanDefinitionNames = context.getBeanDefinitionNames(); for (String beanDefinitionName : beanDefinitionNames) { System.out.println(beanDefinitionName); } } } 复制代码
控制台输出如下,自定义的三个类,包括BeanConfi本身都被容器实例化
entity包中的Person类没有被实例化,是因为Person类上没有添加注解,也即是没有配置bean标签,所以没有注册到容器中,也就没有被实例化,给Person实体类添加一个@Component注解,标识为一个Bean,再次执行测试方法,控制台打印结果如下,Person类被实例化
@ComponentScan源码
includeFilters()的使用
includeFilters()和excludeFilters()返回都是一个Filter数组