依赖注入(DI)的使用和Spring AOP(面向切面编程)
依赖注入的使用
-
以打印机案例深入理解依赖注入
要实现打印机需要创建墨盒Ink接口以及纸张Paper接口
public interface Ink {
public String getColor(int r,int g ,int b);
}
public interface Paper {
public static final String newLine="\r\n";
//输出一个字符到纸张
public void putInChar(char c);
//得到输出到纸张上的内容
public String getContent();
}
使用墨盒和纸张接口开发打印程序Printer
public class Printer {
private Ink ink=null;
private Paper paper=null;
public void setInk(Ink ink) {
this.ink = ink;
}
public void setPaper(Paper paper) {
this.paper = paper;
}
public void print(String str){
System.out.println("使用"+ink.getColor(255,200,0)+"颜色打印:\n");
for (int i = 0; i <str.length() ; i++) {
paper.putInChar(str.charAt(i));
}
System.out.println(paper.getContent());
}
}
编写纸张,彩色 灰色墨盒以及打印纸的实现类
//彩色墨盒
public class ColorInk implements Ink {
@Override
public String getColor(int r, int g, int b) {
Color color = new Color(r, g, b);
return "#"+Integer.toHexString(color.getRGB()).substring(2);
}
}
//灰色墨盒
public class GeryInk implements Ink {
@Override
public String getColor(int r, int g, int b) {
int c=(r+g+b)/3;
Color color = new Color(c,c,c);
return "#"+Integer.toHexString(color.getRGB()).substring(2);
}
}
public class TextPaper implements Paper {
private int charPerLine = 16;
private int linePerPage = 5;
private String content = "";
private int posX = 0;
private int posY = 0;
private int posP = 1;
@Override
public void putInChar(char c) {
content+=c;
++posX;
if (posX==charPerLine){
content+=Paper.newLine;
posX=0;
++posY;
}
if (posY==linePerPage){
content +="==第"+posP+"页==";
content+=Paper.newLine+Paper.newLine;
posY=0;
++posP;
}
}
public void setCharPerLine(int charPerLine){
this.charPerLine=charPerLine;
}
public void setLinePerPage(int linePerPage){
this.linePerPage=linePerPage;
}
@Override
public String getContent() {
String ret = this.content;
if (!(posX == 0 && posY == 0)) {
int count = linePerPage - posY;
for (int i = 0; i < count; i++) {
ret += "==第" + posP + "页==";
}
}
return ret;
}
}
配置打印机的xml文件spring_Context.xml,组装打印机
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="greyInk" class="com.bdqn.IOC.GeryInk"/>
<bean id="colorInk" class="com.bdqn.IOC.ColorInk"/>
<bean id="a4paper" class="com.bdqn.IOC.TextPaper">
<property name="charPerLine" value="10"/>
<property name="linePerPage" value="80"/>
</bean>
<bean id="b5paper" class="com.bdqn.IOC.TextPaper">
<property name="charPerLine" value="6"/>
<property name="linePerPage" value="5"/>
</bean>
<bean id="printer" class="com.bdqn.IOC.Printer">
<property name="ink" ref="colorInk"/>
<property name="paper" ref="b5paper"/>
</bean>
</beans>
编写测试类
@Test
public void TestPrint(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring_Context.xml");
Printer printer=(Printer) context.getBean("printer");
String content="控制反转也称依赖注入,是面对对象编程中的一种设计理念,用于降低程序代码间的耦合度。在不使用Spring时,创建对象需要我们主动去new," +
"A和B要一起完成一件事,A需要用到B这件事才能做到,这就叫A对B产生了依赖,使用了Spring以后,不需要我们去手动new对象," +
"把new对象的权利交给了第三方,这样A就不再依赖于B,所以控制反转I是说创建对象的控制权进行转移," +
"以前创建对象的主动权和创建时机是由自己把控的,而现在这种权力转移到第三方\n";
printer.print(content);
}
}
测试结果如下:
—分割线-----------
Spring AOP(面向切面编程)
面向切面编程AOP(Aspect Oriented Programming)是编程软件思想发展到一定阶段的产物,是面向对象编程的有益补充,AOP一般适用于具有横切逻辑的场合,如访问控制,事务管理,性能检测等。
面向切面编程AOP的基本概念
- 切面(Aspect):一个模块化的横切逻辑,可能会横切多个对象。
- 连接点(Join Point):程序执行中的某个具体执行头。
- 增强处理(Advice):切面在某个特定连接点上执行的代码逻辑
- 切入点(Pointcut):对连接点的特征进行描述,可以使用正则表达式。增强处理和一个切入点表达式相关联,并在与这个切入点匹配的某个连接点上运行。
- 目标对象(Target object):被一个或多个切面增强的对象。
- AOP代理(AOP proxy):由AOP框架所创建的对象,实现执行增强处理方法等功能。
- 织入(Weaving):将增强处理连接到应用程序中的类型或对象上的过程。
- 增强处理类型:前置增强,后置增强,环绕增强,异常抛出异常,最终增强等。
前置增强,后置增强,后置增强带返回值,后置增强带异常的实现
首先需要编写俩个类,一个为目标增强类命名为Target,一个增强类AdviceTarget。
public class Target {
public String show(String name){
System.out.println("这是目标方法");
return "hello"+name;
}
}
//增强类
public class AviceTarget {
//前置增强
public void before(JoinPoint jp){
System.out.println( "参数:"+jp.getArgs()+"方法名"+jp.getSignature()+"目标对象"+jp.getTarget());
}
//后置增强
public void after(JoinPoint jp){
System.out.println("这是后置");
}
//后置增强带返回值
public void afterReturn(JoinPoint jp ,String value){
System.out.println("这是后置带返回值"+value);
}
//后置增强带异常
public void afterException(JoinPoint jp , Exception ex) throws Exception {
System.out.println("后置带异常"+ex);
if (1/0==1){
throw new Exception("除数不为0");
}
}
}
编写增强的xml文件spring_aop.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="target" class="com.bdqn.aop.Target"/> <!--增强目标类bean-->
<bean id="advicetarget" class="com.bdqn.aop.AviceTarget"/> <!--增强类bean-->
<aop:config>
<aop:pointcut id="pointcut" expression="execution(public String show(String ))"/> <!--设置切入点,切入点为Target类的show()方法-->
<aop:aspect ref="advicetarget">
<aop:before method="before" pointcut-ref="pointcut"></aop:before> <!--前置增强-->
<aop:after method="after" pointcut-ref="pointcut"></aop:after> <!--后置增强-->
<aop:after-returning method="afterReturn" pointcut-ref="pointcut" returning="value"></aop:after-returning> <!--后置增强带返回值-->
<aop:after-throwing method="afterException" pointcut-ref="pointcut" throwing="ex"></aop:after-throwing> <!--后置增强带异常-->
</aop:aspect>
</aop:config>
</beans>
编写测试类 把上面四个都写在了一个测试类
@Test
public void TestAop(){
ApplicationContext context = new ClassPathXmlApplicationContext ("spring_aop.xml");
Target target=(Target) context.getBean("target");
try {
target.show("mary0");
} catch (Exception e) {
e.printStackTrace();
}
}
测试结果