我是Java和Spring的新手。我想知道是否有可能,如果是这样的话,我怎样才能将我的方面应用于多个课程,而不必从课程中调用方法" work"。
这是我的主要课程。 Aspects可以处理我从这个类中直接调用的任何方法,但不会对其他类调用的任何其他方法起作用(即使它们不是内部的)
public class AopMain {
public static void main(String[] args) {
String selection = "on";
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
do {
try{
System.out.println("Enter 'length' for a length conversion and 'temperature' for a temperature conversion and 'quit' to quit");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
selection = br.readLine();
if(selection.contentEquals("length")) {
LengthService lengthService = ctx.getBean("lengthService", LengthService.class);
lengthService.runLengthService();
lengthService.display();
}
else if(selection.contentEquals("temperature")) {
TemperatureService temperatureService = new TemperatureService();
temperatureService.runTempertureService();
temperatureService.display();
}
}
catch (Exception e) {
System.out.println("Input error");
}
} while (!selection.contentEquals("quit"));
}
}
这是转换服务类之一:
public class TemperatureService {
String fromUnit = null;
String toUnit = null;
double val = 0;
double converted = 0;
public void runTempertureService() {
Scanner in = new Scanner(System.in);
System.out.println("Convert from (enter C, K, F): ");
fromUnit = in.nextLine();
System.out.println("Convert to (enter C, K, F): ");
toUnit = in.nextLine();
TemperatureConverter from = new TemperatureConverter(fromUnit);
TemperatureConverter to = new TemperatureConverter(toUnit);
System.out.println("Value:");
val = in.nextDouble();
double celcius = from.toCelcius(val);
converted = to.fromCelcius(celcius);
from.display(val, fromUnit, converted, toUnit);
System.out.println(val + " " + fromUnit + " = " + converted + " " + toUnit);
}
public String[] display(){
String[] displayString = {Double.toString(val), fromUnit, Double.toString(converted), toUnit};
return displayString;
}
}
这是转换类之一:
public class TemperatureConverter {
final double C_TO_F = 33.8;
final double C_TO_C = 1;
final double C_TO_KELVIN = 274.15;
private double factor;
public TemperatureConverter(String unit) {
if (unit.contentEquals("F"))
factor = C_TO_F;
else if(unit.contentEquals("C"))
factor = C_TO_C;
else if(unit.contentEquals("K"))
factor = C_TO_KELVIN;
}
public double toCelcius(double measurement) {
return measurement * factor;
}
public double fromCelcius(double measurement) {
return measurement/factor;
}
public TemperatureConverter() {}
public void display(double val, String fromUnit, double converted, String toUnit) {}
}
这是我的配置文件:
<?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" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<aop:aspectj-autoproxy/>
<bean name= "lengthConverter" class= "converter.method.LengthConverter"/>
<bean name= "temperatureConverter" class= "converter.method.TemperatureConverter"/>
<bean name= "lengthService" class= "converter.service.LengthService" autowire = "byName"/>
<bean name= "temperatureService" class= "converter.service.TemperatureService"/>
<bean name="ValidationAspect" class= "converter.aspect.ValidationAspect" />
<bean name="DisplayAspect" class= "converter.aspect.DisplayAspect" />
</beans>
我希望能够将一个方面应用于服务类调用的转换器类的函数,但是就像我刚才提到的那样,它无法直接从主类调用该方法。 (显示功能最初是转换器类的一部分,但我移动它以便方面可以工作)。另外为什么方面不会接受newline()方法调用?
修改
这是我的一个方面:
@Aspect
public class DisplayAspect {
@AfterReturning(pointcut = "execution(* display(..))", returning = "retVal")
public void fileSetUp(Object retVal) {
System.out.println("So we found the display things");
Writer writer = null;
String[] returnArray = (String[]) retVal;
try {
System.out.println("inside try");
String text = "The opertion performed was: " + returnArray[0] + " in " + returnArray[1] + " is " + returnArray[2] + " " + returnArray[3] + "\n";
File file = new File("Log.txt");
writer = new BufferedWriter(new FileWriter(file, true));
writer.write(text);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
答案 0 :(得分:0)
我希望能够将一个方面应用于转换器类的功能
好吧,然后更改你的切入点,以便拦截你想要在你的建议中处理的方法(不是函数,它们被称为方法)。目前切入点是
execution(* display(..))
即。它将使用任意数量的参数和任何返回类型拦截名为display
的所有方法。如果您想要拦截所有转换器方法,请将其更改为
execution(* converter.method.TemperatureConverter.*(..))
代替。
像我刚才提到的那样,它无法直接从主类调用方法。
我需要猜测,因为这个描述不清楚,但可能你要描述的是,只有在从类外部调用TemperatureService.display()
而不是从{{1 }}。这是Spring AOP的一个已知且描述良好的限制,请参阅Spring Manual, chapter 9.6, "Proxying mechanisms":由于Spring AOP的基于代理的“AOP lite”方法,这是行不通的,因为对TemperatureService
方法的内部调用是不通过Spring容器创建的动态代理路由。因此,Spring AOP仅适用于bean之间的调用,而不适用于bean内调用。如果您需要拦截内部调用,则需要切换到完整的AspectJ,它可以通过LTW(加载时编织)轻松集成到Spring应用程序中,如chapter 9.8, "Using AspectJ with Spring applications"中所述。