(精简)Spring框架的IoC(替代工厂类实现方法)和AOP(定义规则,约定大于配置)
2014-06-02 21:57
756 查看
Spring的核心框架主要包含两个技术,分别用来处理工厂类,以及事务处理和连接管理的。
两大核心概念
1) IoC:控制反转,在现在的开发中,如果想建立对象并设置属性,是需要先new对象,再通过setter或构造方法设置属性。而使用Spring的IoC后,则是先通过配置声明属性的值或关系,再通过Spring框架建立对象,建立好的对象中就自动设置好了配置的属性。此功能可以替代工厂类。在IoC 中还提出了DI(依赖注入),表示将一个Spring中配置好的类,设置到另一个Spring配置的类中,作为属性使用。
2) AOP:面向切面编程,特点是在不修改原有代码的基础上,为项目加入一个新的功能。Filter过滤器就是一个典型的AOP设计。Spring中则是使用Interceptor拦截器来实现动态代理设计的功能。在这里主要实现的就是连接的关闭,以及事务的提交和回滚操作,使用这个AOP的功能后,Service的实现类中就不再需要自己编写try…catch…finallly等操作,由Spring自动完成。
Spring的主要组成部件:
1) SpringCore核心组件:实现的是IoC功能。
2) SpringAOP组件:实现的是AOP功能
3) SpringPersistence API:Spring针对持久化操作(JDBC)的支持。
4) SpringORMapping:Spring针对ORMapping框架的支持,可以结合Hibernate,iBATIS,JDO联合开发
5) SpringWeb:Spring针对Web端框架的支持,可以结合Struts2,WebWork联合开发
6) SpringMVC:Spring提供的一个前端框架,可以替代Struts2,完成前台的操作。
7) SpringTest:针对JUnit的支持。
8) SpringAnnotation:在Spring 2.5版加入,在3.0完善的,可以替代XML形式的配置(推荐使用)
建立项目,并加入Spring支持。加入Spring 的核心jar。
![](http://img.blog.csdn.net/20140508101340359)
建立好核心配置文件。
![](http://img.blog.csdn.net/20140508101443093)
通过接口实现类的形式,编写一个简单的打印Hello World的功能。
[java]
view plaincopy
public interface IHelloDAO {
public String sayHello(String name);
}
[java]
view plaincopy
public class HelloDAOImpl implements IHelloDAO {
public String sayHello(String name) {
return "Hell World " + name;
}
}
将工厂部分取消,改为通过Spring配置来完成对象的建立。这里在applicationcontext.xml中添加
[java]
view plaincopy
<span style="color:#cc0000;"><bean id="helloDAOImpl" class="org.liky.dao.impl.HelloDAOImpl"></bean></span>
声明一个<bean>,对应一个java的类,这里将HelloDAOImpl声明到Spring中。
同时,id作为这个类的唯一标识,不允许重复,推荐以类名首字母小写,作为这个名称。
测试建立对象
[java]
view plaincopy
public class Test {
public static void main(String[] args) {
// 建立读取配置文件的核心对象
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
// 建立对象,根据id来建立对象
<span style="color:#cc0000;">IHelloDAO dao = (IHelloDAO) ctx.getBean("helloDAOImpl")</span>;
System.out.println(dao.sayHello("test"));
}
}
注:这里建立对象IHelloDAO dao =DAOFactory.getDAOImplInstance().XXX来建立了;
这里并没有体现出Spring的优势,当对象中包含属性时,才能看出Spring建立对象的好处。
这里使用Spring实现数据库连接类,来看Spring配置的优点。
[java]
view plaincopy
public class DataBaseConnection {
private String dbdriver;
private String dburl;
private String username;
private String password;
private Connection conn;
public Connection getConnection() {
try {
if (conn == null || conn.isClosed()) {
Class.forName(dbdriver);
conn = DriverManager.getConnection(dburl, username, password);
}
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
public void close() {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public void setDbdriver(String dbdriver) {
this.dbdriver = dbdriver;
}
public void setDburl(String dburl) {
this.dburl = dburl;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
}
这个类中的数据库连接属性,都通过Spring配置来加入。
修改Spring配置文件。
[html]
view plaincopy
<span style="white-space:pre"> </span><bean <span style="color:#cc0000;">id="dataBaseConnection"</span> class="org.liky.dbc.DataBaseConnection">
<property name="dbdriver" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="dburl" value="jdbc:oracle:thin:@localhost:1521:ORCL"></property>
<property name="username" value="SUNXUN"></property>
<property name="password" value="123"></property>
</bean>
通过SPring建立出的dbc对象,就包含了连接的各种属性,也就可以直接建立出数据库连接了。
[java]
view plaincopy
public class Test {
public static void main(String[] args) {
// 建立读取配置文件的核心对象
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
DataBaseConnection dbc = (DataBaseConnection) ctx
.getBean("dataBaseConnection");
System.out.println(dbc.getConnection());
}
}
这里只能体现出后期维护中,这种配置的好处。
除此以外,如果在DAOImpl中想使用数据库连接,也可以通过Spring自动注入完成,这里使用的功能就是依赖注入(很形象)。
[java]
view plaincopy
public class HelloDAOImpl implements IHelloDAO {
private DataBaseConnection dbc;
public String sayHello(String name) {
System.out.println(dbc.getConnection());
return "Hell World " + name;
}
public void setDbc(DataBaseConnection dbc) {
this.dbc = dbc;
}
}
修改配置文件(需要在id=helloDAOImpl的注入id=dataBaseConnection的对象)。
[java]
view plaincopy
<span style="white-space:pre"> </span><bean id="helloDAOImpl" class="org.liky.dao.impl.HelloDAOImpl">
<property name="dbc">
<ref bean="dataBaseConnection"/>
</property>
</bean>
通过测试,可以发现,dbc使用的是单例设计模式。
也就是说,Spring中所有的<bean>默认都是单例设计。
如果不想使用单例设计,可以通过设置scope属性来处理。
[java]
view plaincopy
<bean id="dataBaseConnection" <span style="color:#cc0000;">scope="prototype"</span> class="org.liky.dbc.DataBaseConnection">
<property name="dbdriver" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="dburl" value="jdbc:oracle:thin:@localhost:1521:ORCL"></property>
<property name="username" value="SUNXUN"></property>
<property name="password" value="123"></property>
</bean>
除了这种基本配置以外,Spring还支持加入一些集合配置,可以为集合设置默认值。
例如:
1) List
[java]
view plaincopy
<span style="white-space:pre"> </span><property name="all">
<list>
<value>zhangsan</value>
<value>123</value>
<ref bean="dataBaseConnection" />
<value>zhangsan</value>
</list>
</property>
2) Set
[java]
view plaincopy
<span style="white-space:pre"> </span><property name="all">
<set>
<value>zhangsan</value>
<value>123</value>
<ref bean="dataBaseConnection" />
<value>zhangsan</value>
</set>
</property>
3) Map
[java]
view plaincopy
<span style="white-space:pre"> </span><property name="all">
<map>
<entry key="zhangsan">
<value>123</value>
</entry>
<entry key-ref="dataBaseConnection">
<ref bean="dataBaseConnection"/>
</entry>
</map>
</property>
4) Properties
[java]
view plaincopy
<span style="white-space:pre"> </span><property name="all">
<props>
<prop key="zhangsan">123</prop>
<prop key="lisi">abc</prop>
</props>
</property>
AOP使用的原理,实际上是JavaSE里反射类库中的Proxy类。
但在Spring中,由于Proxy类的代码比较复杂,通,因此对其进行了封装过MethodInterceptor的接口来实现代理功能。
这里先编写一个代理规则类。
注意,项目支持中,需要多加入一个AOP的支持库。
![](http://img.blog.csdn.net/20140508105857750)
同时,修改ServiceImpl类,简化代码。
[java]
view plaincopy
public class HelloServiceImpl implements IHelloService {
private IHelloDAO hellodao;
private DataBaseConnection dbc;
public String say(String name) {
return hellodao.sayHello(name);
}
这里的try…catch…finally的代码,会单独编写到规则类中完成(规则)。
[java]
view plaincopy
public class ConnectionInterceptor implements MethodInterceptor {
private DataBaseConnection dbc;
// 在此方法中,编写代码规则.
public Object invoke(MethodInvocation mi) throws Throwable {
Object obj = null;
try {
// 动态调用该调用的SErvice操作.
obj = mi.proceed();
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("拦截器中关闭连接....");
dbc.close();
}
return obj;
}
public void setDbc(DataBaseConnection dbc) {
this.dbc = dbc;
}
}
配置这个类所要应用的规则,即哪些类需要使用这套规则来关闭连接。(约定大于配置)
[java]
view plaincopy
<bean id="connectionInterceptor" class="org.liky.interceptor.ConnectionInterceptor">
<property name="dbc">
<ref bean="dataBaseConnection" />
</property>
</bean>
<!--
配置应用规则
-->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!--
<span style="color:#cc0000;">哪些<bean>需要使用上面的拦截器规则
只要保证命名规范,这里的配置就是固定的.</span>
-->
<property name="beanNames">
<list>
<value>*ServiceImpl</value>
</list>
</property>
<!--
所使用的拦截器
-->
<property name="interceptorNames">
<list>
<value>connectionInterceptor</value>
</list>
</property>
</bean>
这篇博文这是简单介绍下Spring框架的IoC控制反转(替代工厂类实现方法)和AOP面向切面编程(定义规则,约定大于配置);后面博文会再详细说明它分别与JDBC、Struts联合开发的一些程序。
两大核心概念
1) IoC:控制反转,在现在的开发中,如果想建立对象并设置属性,是需要先new对象,再通过setter或构造方法设置属性。而使用Spring的IoC后,则是先通过配置声明属性的值或关系,再通过Spring框架建立对象,建立好的对象中就自动设置好了配置的属性。此功能可以替代工厂类。在IoC 中还提出了DI(依赖注入),表示将一个Spring中配置好的类,设置到另一个Spring配置的类中,作为属性使用。
2) AOP:面向切面编程,特点是在不修改原有代码的基础上,为项目加入一个新的功能。Filter过滤器就是一个典型的AOP设计。Spring中则是使用Interceptor拦截器来实现动态代理设计的功能。在这里主要实现的就是连接的关闭,以及事务的提交和回滚操作,使用这个AOP的功能后,Service的实现类中就不再需要自己编写try…catch…finallly等操作,由Spring自动完成。
Spring的主要组成部件:
1) SpringCore核心组件:实现的是IoC功能。
2) SpringAOP组件:实现的是AOP功能
3) SpringPersistence API:Spring针对持久化操作(JDBC)的支持。
4) SpringORMapping:Spring针对ORMapping框架的支持,可以结合Hibernate,iBATIS,JDO联合开发
5) SpringWeb:Spring针对Web端框架的支持,可以结合Struts2,WebWork联合开发
6) SpringMVC:Spring提供的一个前端框架,可以替代Struts2,完成前台的操作。
7) SpringTest:针对JUnit的支持。
8) SpringAnnotation:在Spring 2.5版加入,在3.0完善的,可以替代XML形式的配置(推荐使用)
一、Spring的IoC功能(掌握)
这里先使用SpringIoC实现打印HelloWorld的功能,来看其替代工厂实现的方法。建立项目,并加入Spring支持。加入Spring 的核心jar。
建立好核心配置文件。
通过接口实现类的形式,编写一个简单的打印Hello World的功能。
[java]
view plaincopy
public interface IHelloDAO {
public String sayHello(String name);
}
[java]
view plaincopy
public class HelloDAOImpl implements IHelloDAO {
public String sayHello(String name) {
return "Hell World " + name;
}
}
将工厂部分取消,改为通过Spring配置来完成对象的建立。这里在applicationcontext.xml中添加
[java]
view plaincopy
<span style="color:#cc0000;"><bean id="helloDAOImpl" class="org.liky.dao.impl.HelloDAOImpl"></bean></span>
声明一个<bean>,对应一个java的类,这里将HelloDAOImpl声明到Spring中。
同时,id作为这个类的唯一标识,不允许重复,推荐以类名首字母小写,作为这个名称。
测试建立对象
[java]
view plaincopy
public class Test {
public static void main(String[] args) {
// 建立读取配置文件的核心对象
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
// 建立对象,根据id来建立对象
<span style="color:#cc0000;">IHelloDAO dao = (IHelloDAO) ctx.getBean("helloDAOImpl")</span>;
System.out.println(dao.sayHello("test"));
}
}
注:这里建立对象IHelloDAO dao =DAOFactory.getDAOImplInstance().XXX来建立了;
这里并没有体现出Spring的优势,当对象中包含属性时,才能看出Spring建立对象的好处。
这里使用Spring实现数据库连接类,来看Spring配置的优点。
[java]
view plaincopy
public class DataBaseConnection {
private String dbdriver;
private String dburl;
private String username;
private String password;
private Connection conn;
public Connection getConnection() {
try {
if (conn == null || conn.isClosed()) {
Class.forName(dbdriver);
conn = DriverManager.getConnection(dburl, username, password);
}
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
public void close() {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public void setDbdriver(String dbdriver) {
this.dbdriver = dbdriver;
}
public void setDburl(String dburl) {
this.dburl = dburl;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
}
这个类中的数据库连接属性,都通过Spring配置来加入。
修改Spring配置文件。
[html]
view plaincopy
<span style="white-space:pre"> </span><bean <span style="color:#cc0000;">id="dataBaseConnection"</span> class="org.liky.dbc.DataBaseConnection">
<property name="dbdriver" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="dburl" value="jdbc:oracle:thin:@localhost:1521:ORCL"></property>
<property name="username" value="SUNXUN"></property>
<property name="password" value="123"></property>
</bean>
通过SPring建立出的dbc对象,就包含了连接的各种属性,也就可以直接建立出数据库连接了。
[java]
view plaincopy
public class Test {
public static void main(String[] args) {
// 建立读取配置文件的核心对象
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
DataBaseConnection dbc = (DataBaseConnection) ctx
.getBean("dataBaseConnection");
System.out.println(dbc.getConnection());
}
}
这里只能体现出后期维护中,这种配置的好处。
除此以外,如果在DAOImpl中想使用数据库连接,也可以通过Spring自动注入完成,这里使用的功能就是依赖注入(很形象)。
[java]
view plaincopy
public class HelloDAOImpl implements IHelloDAO {
private DataBaseConnection dbc;
public String sayHello(String name) {
System.out.println(dbc.getConnection());
return "Hell World " + name;
}
public void setDbc(DataBaseConnection dbc) {
this.dbc = dbc;
}
}
修改配置文件(需要在id=helloDAOImpl的注入id=dataBaseConnection的对象)。
[java]
view plaincopy
<span style="white-space:pre"> </span><bean id="helloDAOImpl" class="org.liky.dao.impl.HelloDAOImpl">
<property name="dbc">
<ref bean="dataBaseConnection"/>
</property>
</bean>
通过测试,可以发现,dbc使用的是单例设计模式。
也就是说,Spring中所有的<bean>默认都是单例设计。
如果不想使用单例设计,可以通过设置scope属性来处理。
[java]
view plaincopy
<bean id="dataBaseConnection" <span style="color:#cc0000;">scope="prototype"</span> class="org.liky.dbc.DataBaseConnection">
<property name="dbdriver" value="oracle.jdbc.driver.OracleDriver"></property>
<property name="dburl" value="jdbc:oracle:thin:@localhost:1521:ORCL"></property>
<property name="username" value="SUNXUN"></property>
<property name="password" value="123"></property>
</bean>
除了这种基本配置以外,Spring还支持加入一些集合配置,可以为集合设置默认值。
例如:
1) List
[java]
view plaincopy
<span style="white-space:pre"> </span><property name="all">
<list>
<value>zhangsan</value>
<value>123</value>
<ref bean="dataBaseConnection" />
<value>zhangsan</value>
</list>
</property>
2) Set
[java]
view plaincopy
<span style="white-space:pre"> </span><property name="all">
<set>
<value>zhangsan</value>
<value>123</value>
<ref bean="dataBaseConnection" />
<value>zhangsan</value>
</set>
</property>
3) Map
[java]
view plaincopy
<span style="white-space:pre"> </span><property name="all">
<map>
<entry key="zhangsan">
<value>123</value>
</entry>
<entry key-ref="dataBaseConnection">
<ref bean="dataBaseConnection"/>
</entry>
</map>
</property>
4) Properties
[java]
view plaincopy
<span style="white-space:pre"> </span><property name="all">
<props>
<prop key="zhangsan">123</prop>
<prop key="lisi">abc</prop>
</props>
</property>
二、Spring的AOP功能(了解)
AOP:面向切面编程,特点是在不修改原有代码的基础上,为项目加入一个新的功能。Filter过滤器就是一个典型的AOP设计。AOP使用的原理,实际上是JavaSE里反射类库中的Proxy类。
但在Spring中,由于Proxy类的代码比较复杂,通,因此对其进行了封装过MethodInterceptor的接口来实现代理功能。
这里先编写一个代理规则类。
注意,项目支持中,需要多加入一个AOP的支持库。
同时,修改ServiceImpl类,简化代码。
[java]
view plaincopy
public class HelloServiceImpl implements IHelloService {
private IHelloDAO hellodao;
private DataBaseConnection dbc;
public String say(String name) {
return hellodao.sayHello(name);
}
这里的try…catch…finally的代码,会单独编写到规则类中完成(规则)。
[java]
view plaincopy
public class ConnectionInterceptor implements MethodInterceptor {
private DataBaseConnection dbc;
// 在此方法中,编写代码规则.
public Object invoke(MethodInvocation mi) throws Throwable {
Object obj = null;
try {
// 动态调用该调用的SErvice操作.
obj = mi.proceed();
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("拦截器中关闭连接....");
dbc.close();
}
return obj;
}
public void setDbc(DataBaseConnection dbc) {
this.dbc = dbc;
}
}
配置这个类所要应用的规则,即哪些类需要使用这套规则来关闭连接。(约定大于配置)
[java]
view plaincopy
<bean id="connectionInterceptor" class="org.liky.interceptor.ConnectionInterceptor">
<property name="dbc">
<ref bean="dataBaseConnection" />
</property>
</bean>
<!--
配置应用规则
-->
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!--
<span style="color:#cc0000;">哪些<bean>需要使用上面的拦截器规则
只要保证命名规范,这里的配置就是固定的.</span>
-->
<property name="beanNames">
<list>
<value>*ServiceImpl</value>
</list>
</property>
<!--
所使用的拦截器
-->
<property name="interceptorNames">
<list>
<value>connectionInterceptor</value>
</list>
</property>
</bean>
这篇博文这是简单介绍下Spring框架的IoC控制反转(替代工厂类实现方法)和AOP面向切面编程(定义规则,约定大于配置);后面博文会再详细说明它分别与JDBC、Struts联合开发的一些程序。
相关文章推荐
- (精简)Spring框架的IoC(替代工厂类实现方法)和AOP(定义规则,约定大于配置)
- aop(面向切面)编程思想在spring框架下实现的配置方法
- Unity IOC容器通过配置实现类型映射的几种基本使用方法
- 深入浅出学习Spring框架(四):IoC和AOP的应用——事务配置
- 零配置实现Spring IoC与AOP
- 【SSH进阶之路】一步步重构容器实现Spring框架——配置文件+反射实现IoC容器(十)
- SpringMVC实现Controller的两种方法:配置和约定
- Spring配置AOP实现定义切入点和织入增强
- AndroidStudio 配置 AspectJ 环境实现AOP的方法
- 【SSH进阶之路】一步步重构容器实现Spring框架——配置文件+反射实现IoC容器(十)
- Spring AOP详解及通过XML配置实现的实现方法
- 在Spring框架中用AOP实现WEB服务的方法
- 菜鸟学习Spring——60s配置XML方法实现简单AOP
- Spring框架中的aop操作之二 通过配置文件实现增强
- Spring框架实现IOC的两种方法、Xml中bean语法
- 【SSH进阶之路】一步步重构容器实现Spring框架——配置文件+反射实现IoC容器(十)
- Spring框架AOP的配置和实现的简单例子
- 【SSH进阶之路】一步步重构容器实现Spring框架——配置文件+反射实现IoC容器(十)
- Spring Aop之AspectJ注解配置实现日志管理的方法
- Spring框架IOC和AOP的实现原理与详解