了解AOP
// 需要在某个knight.embark()前后执行某写方法
public class knight(){
// 需要被注入的属性
private Minstrel minstrel;
public Knight(Minstrel minstrel){
this.minstrel = minstrel;
}
public void embark(){
this.minstrel.beforeEmbark();
knightEmbark();
this.minstrel.afterEmbark();
}
}
public class Minstrel{
// 需要被注入的属性
private PrintStream printStream;
public Minstrel(PrintStream printStream){
this.printStream=printStream;
}
public void beforeEmbark(){
printStream.println("123");
}
public void afterEmbark(){
printStream.printLn("456");
}
}
- 缺点:
- 需要在方法内显式的调用才能被执行(他们或许本应是独立工作)
- minstrel为null呢?
- embark()方法变得复杂了,混入了其他的与其无关的方法
使用了AOP之后
<beans>
<bean id="knight" class="com.springinaction.Knight">
</bean>
<bean id="minstrel" class="com.springinaction.Minstrel">
<!-- 使用spring语法注入变量 -->
<constructor-arg value="#{T(System).out}"/>
</bean>
<!-- 声明切面 -->
<aop:config>
<aop:aspect>
<aop:pointcut id="embark" expression="excution(* *.embark(..))"/>
<aop:before pointcut_ref="embark" method="beforeEmbark"/>
<aop:after pointcut_ref="embark" method="afterEmbark"/>
</aop:aspect>
</aop:config>
</beans>
- 优点:
- 解耦–Knight不知道 Minstrel 为谁,甚至不知道是否在其前后被调用
- 保证方法粒度中的代码纯粹性
- Minstrel仍是一个POJO,在Spring中被声明为切面
- Minstrel被声明为一个切面之前,需先被声明为一个bean–也就是说你也可以为一个被用作切面的POJO注入依赖
templates – 精简无用的口水代码
/**
1.声明Connection/PreperStatement/ResultSet
2.获取DataSource/获取Connection
3.获取PreperStatement传入SQL语句和变量
4.执行获取ResultSet,处理结果集
5.释放资源
*/
- 使用Spring封装好的jdbcTemplate,则只需要专注于准备SQL语句和处理结果集
this.jdbcTempate.excuteQuery("sql",params,new RowMapper<T>(){
public T mapRow(ResultSet rs,int rowNum){
//处理结果集
}
});
DI,AOP,templates 都是为了将结构复杂的java代码进行简化
Container容器
- 两种容器:
- BeanFactory 提供最简单的依赖注入支持
- ApplicationContext 额外提供应用级的功能如阅读propertis文件和添加监听 (通常使用这种)
几种ApplicationContext
- AnnotationConfigApplicationContext – 解析注解的class类以生成context
- AnnotationConfigWebApplicationContext – webApplication中使用
- ClassPathXmlApplicationContext – 解析XML文件以生成context,以classpath为基本路径
- FileSystemXmlApplicationContext – 解析XML文件以生成context,以FileSystem(系统默认文件路径)为基本路径
- XmlWebApplicationContext – webApplication中使用