概述
一、Spring概述
Spring框架图
Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的javabean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分java应用都可以从Spring中受益。总结一句话:Spring是一个轻量级控制反转(IOC)和面向切面(AOP)的容器框架。Spring致力于将其他的框架融合在一起,而不是去与他们竞争。
从上图的框架图中,主要讲解一下下面几个概念:
1、core
核心容器,是Spring框架最基础的部分,它提供了依赖注入(DI---Dependencylnjection)特征来实现容器对bean的管理。这里最基本的概念是BeanFactory,它是任何Spring应用的核心。BeanFactory是工厂模式的一个实现,它使用IOC将应用配置和依赖说明从实际的代码中分离出来。
2、AOP
提供了对面向切面编程的丰富支持。
3、DAO
使用JDBC经常导致大量的重复代码,取得连接、创建语句、处理结果集,然后关闭连接。Spring的JDBC和DAO模块抽取了这些重复代码,因此你可以保持你的数据库访问代码干净简洁,并且可以防止因关闭数据库资源失败而引起的问题。这个模块还使用了Spring的AOP模块为Spring应用中的对象提供了事务管理服务。
4、ORM
对那些更喜欢使用对象/关系映射工具而不是直接使用JDBC的人,Spring提供了ORM模块。Spring并不试图实现它自己的ORM解决方案,而是为几种流行的ORM框架提供了集成方案,包括Hibernate、JDO和iBATIS SQL映射。Spring的事务管理支持这些ORM框架中的每一个也包括JDBC。
二、IOC
解释1、IOC(控制反转-Inverse of Control)是Spring容器的内核,AOP、声明式事务等功能在此基础上建立。对于软件上理解:某一接口具体实现类的选择控制权从调用类中移除,转交给第三方决定。用我的话来通俗解释一遍就是:
之前我们在manage层里面new DAO,之后就能直接用dao层中的方法了,这是我们写死的,但是我们现在把new,调用方法,这些交给Spring容器来做,包括new的过程和控制manage调用dao里的方法的过程。--Spring容器控制了,并且把权利从接口实现类反转得到了Spring容器里。
给大家推荐一个博客:http://stamen.iteye.com/blog/1489223/
解释2、控制反转,本来是由应用程序管理的对象之间的依赖关系,现在交给了容器管理,这就叫控制反转,即交给了IOC容器,Spring的IOC容器主要使用DI方式实现的。不需要主动查找,定位和创建,这些都由容器管理。
也就是IOC容器给我们找到要用的DAO之后,送给我们(manage),这个过程就是注入(DI),我们直接用。
好处:
1、大量减少了factory和singleton的数量,使代码层次更加清晰,主要原因是我们不在查找,定位,创建和管理对象之间的依赖关系了,都交给IOC容器管理。
2、Spring的IOC容器是一个轻量级的容器,没有侵入性,不需要依赖容器的API,也不需要实现一些特殊的接口。
3、一个合理的设计最好避免侵入性。
4、鼓励了我们面向接口编程,减少了代码中的耦合(解耦合),将耦合推迟到了配置文件中,发生了变化也更容易控制。
那么有几种IOC管理方法呢?
1、构造函数
配置文件写法:
<bean id="userDao4Mysql" class="com.bjpowernode.spring.dao.UserDao4MySqlImpl"/>
<bean id="usrDao4Oracle" class="com.bjpowernode.spring.dao.UserDao4OracleImpl"/>
上面这两个是具体实现接口的类,他们实现的是dao层的接口。
下面这个manage层的实现类。直接把dao用那个类写进去了。ref名称和上面的id对应。
<bean id="userManager" class="com.bjpowernode.spring.manager.UserManagerImpl">
<constructor-arg ref="userDao4Mysql"/>
</bean>
这样还可以换,更方便了。
代码里:
UserManage是一个接口
package com.bjpowernode.spring.manager;
public interface UserManager {
public void addUser(String username, String password);
}
userManagerImpl是一个实现了userManage接口的方法
(在这里的manage实现层里,写了个构造函数,将dao的接口放进去了,没有指定是谁实现,在配置文件中写好的。控制反转!控制权交给了容器!)
package com.bjpowernode.spring.manager;
import com.bjpowernode.spring.dao.UserDao;
public class UserManagerImpl implements UserManager {
private UserDao userDao;
public UserManagerImpl(UserDao userDao) {
this.userDao = userDao;
}
这样就属于让Spring把userdao的实现注入过来的构造函数的方法。
那么,客户端如何调用这个方法呢?
package com.bjpowernode.spring.client;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.bjpowernode.spring.dao.UserDao4MySqlImpl;
import com.bjpowernode.spring.manager.UserManager;
import com.bjpowernode.spring.manager.UserManagerImpl;
public class Client {
public static void main(String[] args) {
ApplicationContext factory = new ClassPathXmlApplicationContext("applicationContext.xml");
UserManager userManager = new UserManagerImpl(new UserDao4MySqlImpl());
userManager.addUser("张三", "123");
}
}
2、Setter方法
和上述构造方函数方法的区别就在:
public class UserManagerImpl implements UserManager {
private UserDao userDao;
public void setUserDao(UserDao userDao){
this.userDao=userDao;
}
配置文件的区别:
<bean id="userManager" class="com.bjpowernode.spring.manager.UserManagerImpl">
<property name="userDao" ref="userDao4Mysql">
</bean>
客户端:
public class Client {
public static void main(String[] args) {
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
UserManager userManager = (UserManager)factory.getBean("userManager");
userManager.addUser("张三", "123");
}
}
用途区别:
当我们想在new manage的时候就调用dao层,那么就用构造方式,如果没有这种需求,就可以用setter方法。鼓励用后者,参数少了用构造方法。
常用属性的注入
String、int、list、Set、String[]、Map
java类:
public class Bean1{
private String strValue;
private String intValue;
private List listValue;
private Set setValue;
private String[] arryValue;
private Map mapValue;
//下方设置上get/set方法
}
配置文件:
<bean id="bean1" class="com.Bean1">
<property name="strValue" value="Hello_spring"/>
<property name="intValue" value="123"/>
<property name="listValue">
<list>
<value>list1</value>
<value>list2</value>
</list>
</property>
//set/array同上写法
<property name="mapValue">
<map>
<entry key="k1" value="v1"/>
<entry key="k2" value="v2"/>
</map>
</property>
</bean>
private String strValue;
private String intValue;
private List listValue;
private Set setValue;
private String[] arryValue;
private Map mapValue;
//下方设置上get/set方法
}
配置文件:
<bean id="bean1" class="com.Bean1">
<property name="strValue" value="Hello_spring"/>
<property name="intValue" value="123"/>
<property name="listValue">
<list>
<value>list1</value>
<value>list2</value>
</list>
</property>
//set/array同上写法
<property name="mapValue">
<map>
<entry key="k1" value="v1"/>
<entry key="k2" value="v2"/>
</map>
</property>
</bean>
只要我们在。java文件里提供set方法,Spring的IOC容器就会把值注入。
client端取值
其中,涉及到自动转换机制,当然日期类型的,需要属性编辑器来转换。
请使用手机"扫一扫"x