java – 为什么我需要一个公共方法来使我的注释工作?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – 为什么我需要一个公共方法来使我的注释工作?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2972字,纯文字阅读大概需要5分钟。
内容图文
![java – 为什么我需要一个公共方法来使我的注释工作?](/upload/InfoBanner/zyjiaocheng/772/997af4a961e8425b961ccc9fd1d48d4a.jpg)
简而言之,我的问题是如果带注释的方法不是公共的,我的注释会被忽略,但是如果同一个类中的另一个方法被注释,则会被识别.
我正在尝试编写注释来记录方法的执行时间,如this answer中所述.
这是我的注释:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogExecutionTime
{
}
我的方面:
@Component
@Aspect
public class LogTimeAspect
{
@Around(value = "@annotation(annotation)")
public Object logExecutionTime(final ProceedingJoinPoint joinPoint, final LogExecutionTime annotation) throws Throwable
{
final long startingTime = System.currentTimeMillis();
try
{
System.out.println("Starting timed method");
final Object retval = joinPoint.proceed();
return retval;
}
finally
{
System.out.println("Finished. Timed method " + joinPoint.toShortString() + " took: " + (System.currentTimeMillis() - startingTime) + "ms.");
}
}
}
我在其中使用注释的类:
@Component("classToBeAnnotated")
public class ClassToBeAnnotated {
@LogExecutionTime
public void operate() throws InterruptedException {
System.out.println("Performing operation");
Thread.sleep(1000);
}
}
和测试类:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/DefaultApplicationContext.xml" })
public class TestLauncher
{
@Autowired
private ClassToBeAnnotated classToBeAnnotated;
@Test
public void test() throws InterruptedException
{
classToBeAnnotated.operate();
}
}
如果我运行上面显示的代码,我会得到
Starting timed method
Performing operation
Finished. Timed method execution(operate) took: 1025ms.
到现在为止还挺好.但是如果我从带有注释的方法中删除public
@LogExecutionTime
void operate() throws InterruptedException
注释被忽略,我得到:
Performing operation
没有错误,没有警告,只是没有运行.但最令我印象深刻的是,如果我将另一个方法添加到同一个类中,并将其公开并注释它,我会得到与初始条件相同的输出,即使没有调用或与之相关的额外方法除了具有相同的注释之外,原始的任何方式.
@Component("classToBeAnnotated")
public class ClassToBeAnnotated {
@LogExecutionTime
public void someOtherMethod()
{
}
@LogExecutionTime
void operate() throws InterruptedException {
System.out.println("Performing operation");
Thread.sleep(1000);
}
}
输出:
Starting timed method
Performing operation
Finished. Timed method execution(operate) took: 1029ms.
有人可以解释为什么会这样吗?
解决方法:
Spring AOP是一个依赖的“AOP lite”框架
> JDK动态代理(适用于实现一个或多个接口的所有类)或
> CGLIB动态代理(也适用于未实现任何接口的类).
接口定义的方法定义为public,因此JDK动态代理也只能代理公共方法.
CGLIB动态代理通过子类化现有类来工作,将代理放入与基类相同的包中.因此,它可以访问公共,受保护和受包保护的方法,但不能访问私有方法.无论如何,Spring试图统一处理两个变体,仅将AOP限制为公共的非静态方法.
好消息是Spring有一个非常好的原生AspectJ集成,通常通过LTW(加载时编织)激活,参见手册第9.8 Using AspectJ with Spring applications节.但是CTW(编译时编织)也是可能的.查看AspectJ手册以获取更多信息.使用完整的AspectJ,您可以拦截非公共方法,构造函数,成员读/写访问等.虽然Spring AOP仅适用于Spring Beans / Components,但AspectJ适用于任何类,并且不需要任何代理,从而提高了效率.所以你有很多选择,可以使用两全其美.
内容总结
以上是互联网集市为您收集整理的java – 为什么我需要一个公共方法来使我的注释工作?全部内容,希望文章能够帮你解决java – 为什么我需要一个公共方法来使我的注释工作?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。