spring是一个提供了解决J2EE问题的一站式框架。
框架优点
轻量级的容器框架没有侵入性
使用IoC容器更加容易组合对象直接间关系,面向接口编程,降低耦合
DI(依赖注入)
Aop可以更加容易的进行功能扩展,遵循ocp开发原则
创建对象默认是单例的,不需要再使用单例模式进行处理
概念理解:
IoC(控制反转)
首先想说说IoC(Inversion of Control,控制反转)。这是spring的核心,贯穿始终。所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。这是什么意思呢,举个简单的例子,我们是如何找女朋友的?常见的情况是,我们到处去看哪里有长得漂亮身材又好的mm,然后打听她们的兴趣爱好、qq号、电话号、ip号、iq号………,想办法认识她们,投其所好送其所要,然后嘿嘿……这个过程是复杂深奥的,我们必须自己设计和面对每个环节。传统的程序开发也是如此,在一个对象中,如果要使用另外的对象,就必须得到它(自己new一个,或者从JNDI中查询一个),使用完之后还要将对象销毁(比如Connection等),对象始终会和其他的接口或类藕合起来。
那么IoC是如何做的呢?有点像通过婚介找女朋友,在我和女朋友之间引入了一个第三者:婚姻介绍所。婚介管理了很多男男女女的资料,我可以向婚介提出一个列表,告诉它我想找个什么样的女朋友,比如长得像李嘉欣,身材像林熙雷,唱歌像周杰伦,速度像卡洛斯,技术像齐达内之类的,然后婚介就会按照我们的要求,提供一个mm,我们只需要去和她谈恋爱、结婚就行了。简单明了,如果婚介给我们的人选不符合要求,我们就会抛出异常。整个过程不再由我自己控制,而是有婚介这样一个类似容器的机构来控制。Spring所倡导的开发方式就是如此,所有的类都会在spring容器中登记,告诉spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。
简单示例:
新建Java类Hi,具体代码如下,两个变量msg、date,一个初始化函数,一个sayhi函数,4个set get 函数:
package com.test;
import java.util.Date;
public class Hi {
private String msg = null;
private Date date = null;
public void init(){
this.msg = "hi~~";
this.date = new Date();
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public void sayhi(){
System.out.println(msg+"\t"+date);
}
}
//打开配置文件applicationContext.xml,配置以下内容:
1 "1.0" encoding="UTF-8"?>
2 3 xmlns="http://www.springframework.org/schema/beans"
4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5 xmlns:p="http://www.springframework.org/schema/p"
6 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
7
8 "hi" class="com.test.Hi" init-method="init">
9
10
11
//其中:bean中id为bean的标识或者名字,class表示对应的类全名,init-method=“init”表示bean服务启动的时候会执行com.test.Hi中init方法。
新建测试类,编写以下代码,代码含义加载配置文件,取出bean,执行:
1 package com.test;
2
3 import org.springframework.context.ApplicationContext;
4 import org.springframework.context.support.FileSystemXmlApplicationContext;
5 public class Test {
6 public static void main(String[] args) {
7 // TODO Auto-generated method stub
8 ApplicationContext context = new FileSystemXmlApplicationContext("applicationContext.xml");
9 //Spring容器控制Hi对象
Hi hi1 = (Hi) context.getBean("hi");
10 hi1.sayhi();
11 }
12
13 }
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框架去实现。
示例2:
启用Aop功能,即把标签引入配置文件.xml
然后写被代理的类和拓展类:
public class AopMethod {
public void func(){
System.out.println("目标方法");
}
public class ExtMethod {
public void beforeFunc(){
System.out.println("目标方法之前执行");
}
public void AfterFunc(){
System.out.println("目标方法之后执行");
}
}
}
配置文件声明
<bean id="targetclass" class="com.spring.aop.AopMethod ">bean>
<bean id="extendsclass" class="com.spring.aop.ExtMethod ">bean>
<aop:config>
<aop:aspect id="extendAspect" ref="">
<aop:pointcut expression="execution(public ** (..))" id="extendsPoincat">
<aop:before method="beforeFunc" pointcut-ref="extendsPoincat" />
<aop:after method="AfterFunc" pointcut-ref="extendsPoincat" />
aop:aspect>
aop:config>
成功的话,执行目标类中的目标方法func()时,会先执行扩展类中的beforeFunc()方法,再执行目标方法,最后再执行AfterFunc()方法。
也就是我们只需要手动调用func方法,扩展类中的两个方法框架会在执行的时候通过读取配置文件,获取相应信息,自动给我们添加上扩展的方法。。
DI(依赖注入)
IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。比如对象A需要操作数据库,以前我们总是要在A中自己编写代码来获得一个Connection对象,有了 spring我们就只需要告诉spring,A中需要一个Connection,至于这个Connection怎么构造,何时构造,A不需要知道。在系统运行时,spring会在适当的时候制造一个Connection,然后像打针一样,注射到A当中,这样就完成了对各个对象之间关系的控制。A需要依赖 Connection才能正常运行,而这个Connection是由spring注入到A中的,依赖注入的名字就这么来的。那么DI是如何实现的呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。
理解了IoC和DI的概念后,一切都将变得简单明了,剩下的工作只是在spring的框架中堆积木而已。
简单示例:
@Controller
@RequestMapping("/user")
public class UserController {
private static Logger logger = Logger.getLogger(UserController.class);
@Resource //类UserController需要依赖IUserService,在此注入IUserService
private IUserService userService;
@RequestMapping("/showUser")
public String toIndex(HttpServletRequest request,Model model){
logger.debug("ws---0011--------");
int userId = Integer.parseInt(request.getParameter("id"));
//已经注入userService对象,可以直接调用
User user = this.userService.getUserById(userId);
model.addAttribute("user", user);
return "showUser";
}
注解:
@Component:标准一个普通的spring Bean类。
@Controller:标注一个控制器组件类。
@Service:标注一个业务逻辑组件类。
@Repository:标注一个DAO组件类。
注解学习详情:
http://www.cnblogs.com/leskang/p/5445698.html
http://blog.csdn.net/w410589502/article/details/51861296