Spring是分层的Java SE/EE的full-stack轻量级开源框架,以IOC(Inverse of Controll,反转控制)和AOP(Aspect Oriented Programming,面向切面编程)为内核,提供了表示层和持久层以及业务层事务管理等众多企业级开发技术,还能整合开源界诸多著名的第三方框架和类库,逐渐成为使用最多的企业级Java EE开发的首选开源框架。Spring是一个开放源代码的设计层面的框架,他解决的是业务逻辑和其它各层的松耦合问题,它将面向接口的编程思想贯穿整个应用系统。它是2003年开始流行的一个Java EE轻量级开发框架。
spring是J2EE应用程序框架,是轻量级的IoC和AOP的容器框架,主要是针对javaBean的生命周期进行管理的轻量级容器,可以单独使用,也可以和Struts框架,ibatis框架等组合使用。
1)IoC(Inversion of Control)控制反转,对象创建责任的反转,在spring中BeanFacotory是IoC容器的核心接口,负责实例化,定位,配置应用程序中的对象及建立这些对象间的依赖。XmlBeanFacotory实现BeanFactory接口,通过获取xml配置文件数据,组成应用对象及对象间的依赖关系。
spring中有三种注入方式,一种是set注入,一种是接口注入,另一种是构造方法注入。
2)AOP面向切面编程
aop就是纵向的编程,如下图所示,业务1和业务2都需要一个共同的操作,与其往每个业务中都添加同样的代码,不如写一遍代码,让两个业务共同使用这段代码。
spring中面向切面变成的实现有两种方式,一种是动态代理,一种是CGLIB,动态代理必须要提供接口,而CGLIB实现是有继承。
在不使用spring框架之前,我们的service层中要使用dao层的对象,不得不在service层中new一个对象。如下:
//dao层对象
public class UserDao{
publicvoid insert(User user){}
}
//service层对象
public classUserService{
publicvoid insert(User user){
UserDaouserdao = new UserDao();
userdao.insert(user);
}
}
//dao层对象
public class UserDao{
publicvoid insert(User user){}
}
//service层对象
public classUserService{
privateUserDao userdao;
publicUserDao getUserdao() {
returnuserdao;
}
publicvoid setUserdao(UserDao userdao) {
this.userdao= userdao;
}
publicvoid insert(User user){
userdao.insert(user);
}
}
service层要用dao层对象需要配置到xml配置文件中,至于对象是怎么创建的,关系是怎么组合的都交给了spring框架去实现。
BeanFactory创建对象的工厂(它是一个接口),该工厂采用了延迟加载的思想来创建对象即每次获取对象时才创建一个对象。
作用:Spring在启动时会自动创建配置的相关对象,也就是解析完XML文件后就会创建对象。
两大实现类:
1) ClassPathXmlApplicationContext:从类路径下查找加载配置文件(只能从类路径下查找加载配置文件)
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml") ;
2) FileSystemXmlApplicationContext:从硬盘绝对路径下查找加载配置文件
FileSystemXmlApplicationContext context=new FileSystem XmlApplicationContext("D:\\....");
@Component:用来创建一个对象,相当于
@Component是spring框架最初设计的,后来为了标识不同代码层,衍生出@Controller(在控制层使用),@Service(在业务层使用),@Repository(在数据持久层使用)三个注解,作用相当于配置文件的bean标签,被注解的类spring始化时就会创建该对象。这三个注解的用于发@Component一模一样。
添加了注解的类要让spring认识,需要在配置文件中添加如下代码:
@Autowired:该注解自动按照类型注入,只要有唯一的类型匹配就能注入成功。
如果注入的Bean在容器中类型不唯一时,会把变量的名称作为Bean的id,在容器中查找,找到后也能注入成功。如果没有找到一致的Bean的id,则报错。
@Qualifier:该注解在自动按类型注入的基础上,再按照Bean的id注入。他的属性value用于指定Bean的id。在给类成员注入数据时不能独立使用,需要和@Autowired结合使用,但是在给方法的形参注入数据的时候可以单独使用。如下列代码所示:将id值为ds1的DataSource类型的对象注入给方法的形参。
public QueryRunner createQueryRunner(@Qualifier("ds1")DataSource dataSource)
{
return new QueryRunnber(dataSource);
}
@Resource:直接按照Bean的id进行注入,它的name属性定义Bean的id。
当我们使用注解注入时,可以省略set方法。
注意:以上三个注解都是用于注入Bean类型对象的值,对于基本数据类型和String类型需要使用@Value注解。
@Value:给基本数据类型和String类型对象进行注入。
它的属性value用于指定要注入的数值。他可以借助Spring的EL表达式读取Properties配置文件中的内容。
@Scope: 用于改变对象的作用范围,属性value用于指定作用范围的取值,取值和xml文件中scope属性的取值一样:singleton、protoType、request、session、GlobalSession。
定义一个Spring的配置类,代码如下:
//表示当前类为Spring的配置类
@Configuration
//自动注解扫描
@ComponentScan(basePackages="edu.xync.spring")
//导入其他的配置类
@Import({BeanConfig.class,DataSourceConfig.class})
//加载配置文件
@PropertySource(value="classpath:db.properties")
//支持AOP注解
@EnableAspectJAutoProxy
public class SpringConfiguration
{
}
注意理解该类上方添加的各个注解的含义。
测试方法如下:
@Test
public void getObject()
{
ApplicationContext context=new AnnotationConfigApplicationContext(SpringConfiguration.class);
StudentService studentService=(StudentService)context.getBean("studentService");
studentService.add();
}