为什么我用 toString() 得到相同的结果而用 getClass().getName() 得到不同的结果
Why do I get same result with toString() but different result with getClass().getName()
我正在学习AOP,在spring项目中,有如下一段代码
MainDemoApp.java
public class MainDemoApp {
public static void main(String[] args) {
// read spring config java class
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(DemoConfig.class);
// DemoConfig.class is a simple class with just component scanning enabled
// and with @EnableAspectJAutoProxy
// get the bean from spring container
AccountDAO accountDAO = context.getBean("accountDAO", AccountDAO.class);
System.out.println(accountDAO.toString()); // line to be modified
// call the business method
accountDAO.addAccount();
// close the context
context.close();
}
}
AccountDAO.java
@Component
public class AccountDAO {
public void addAccount() {
System.out.println(this.toString()); // line to be modified
}
}
还有我的方面class
MyDemoLoggingAspect.java
@Aspect
@Component
public class MyDemoLoggingAspect {
// this is where we add all our related advices for logging
// let's start with a @Before advice
@Before("execution(public void addAccount())")
public void beforeAddAccountAdvice() {
System.out.println("\n=======>>> Executing @Before Advice");
}
}
现在,当我在 MainDemoApp
中使用 运行 main
方法时,我得到以下输出-
输出-
com.luv2code.aopdemo.dao.AccountDAO@3e0e1046
=======>>> Executing @Before Advice
com.luv2code.aopdemo.dao.AccountDAO@3e0e1046
正如你所看到的线条
System.out.println(accountDAO.toString());
和
System.out.println(this.toString());
给出同样的结果,before advice也执行成功。
默认情况下 toString()
定义为-
this.getClass().getName() + "@" + Integer.toHexString(this.hashCode())
但是当我显式打印出 getClass().getName() 时,结果不同
System.out.println(accountDAO.getClass().getName());
和
System.out.println(this.getClass().getName());
输出-
com.luv2code.aopdemo.dao.AccountDAO$$EnhancerBySpringCGLIB$eb61b6
=======>>> Executing @Before Advice
com.luv2code.aopdemo.dao.AccountDAO
两个class名字都不一样,不知道是哪种class名字。
此外,当我显式打印 hashCode()
时,结果也不同。
我对得到不同的结果感到困惑-
toString()
,当 toString()
包括 getClass().getName()
和 hashCode()
getClass().getName()
hashCode()
为什么会有这些差异,我没有覆盖任何这些方法(在我这边),这是否与 AOP 代理有关?
请帮我解开这些疑惑。
编辑-
我也有一个非常奇怪的观察,当我修改
MainDemoApp.java
AccountDAO accountDAO = context.getBean("accountDAO", AccountDAO.class);
System.out.println(accountDAO.hashCode());
// call the business method
accountDAO.addAccount(accountDAO);
而AccountDAO.java
修改为-
public void addAccount(AccountDAO obj) {
System.out.println(this.hashCode() + " " + obj.hashCode());
}
现在 hashCode()
的结果是一样的,但是如果我不更改方法签名并在前一段代码上调用 hashCode()
,结果就不同了
谁也能解释一下吗?
欢迎来到 SO。请注意,在此平台上,最好只提出一个明确的问题,而不是提出很多问题。但我们也尽量对新手友善,所以我试着回答你的问题。虽然这有点多余,因为其他人已经在评论中回复了,但我也认为评论是评论,答案是答案,即答案应该这样写。可能这里的其他贡献者太忙了,无法写出全面的答案,所以我在这里接球。
System.out.println(accountDAO.toString());
And
System.out.println(this.toString());
give the same result
这是因为 accountDAO
是一个动态代理,而您正在对其应用 Spring AOP 方面。它正在将方法调用转发给它的委托(它正在代理的原始对象)。
But when I explicitly print out getClass().getName() the results are different
System.out.println(accountDAO.getClass().getName());
And
System.out.println(this.getClass().getName());
Output-
com.luv2code.aopdemo.dao.AccountDAO$$EnhancerBySpringCGLIB$eb61b6
=======>>> Executing @Before Advice
com.luv2code.aopdemo.dao.AccountDAO
前者打印 CGLIB 代理的名称 class,后者打印目标 class 名称。
Also when I explicitly print hashCode()
the results are different.
同样的原因:您正在打印代理与原始对象的哈希码。
Why are these differences there, I did not override any of these methods (At my end), does this has something related to AOP proxy?
嗯,在某种程度上你做到了。您应用了一个方面,导致代理创建。所以现在实际的 Spring bean 是一个代理,导致你上面描述的所有效果。从技术上讲,Spring 代理是一个 subclass(或接口实现,取决于您的设置以及您是否代理接口 ot class 类型)。代理保留对原始对象(其委托或目标对象)的引用,并使用附加功能对其进行装饰。这是一个众所周知的设计模式。 Spring 在整个框架中大量使用它。有关详细信息,请参阅 。
关于你的后续问题,根本原因和解释同上。一旦您了解 Spring AOP 使用动态代理并且相同的代理使用委托来实现 decorator pattern.
,这一切都非常简单和合乎逻辑。
我正在学习AOP,在spring项目中,有如下一段代码
MainDemoApp.java
public class MainDemoApp {
public static void main(String[] args) {
// read spring config java class
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(DemoConfig.class);
// DemoConfig.class is a simple class with just component scanning enabled
// and with @EnableAspectJAutoProxy
// get the bean from spring container
AccountDAO accountDAO = context.getBean("accountDAO", AccountDAO.class);
System.out.println(accountDAO.toString()); // line to be modified
// call the business method
accountDAO.addAccount();
// close the context
context.close();
}
}
AccountDAO.java
@Component
public class AccountDAO {
public void addAccount() {
System.out.println(this.toString()); // line to be modified
}
}
还有我的方面class
MyDemoLoggingAspect.java
@Aspect
@Component
public class MyDemoLoggingAspect {
// this is where we add all our related advices for logging
// let's start with a @Before advice
@Before("execution(public void addAccount())")
public void beforeAddAccountAdvice() {
System.out.println("\n=======>>> Executing @Before Advice");
}
}
现在,当我在 MainDemoApp
中使用 运行 main
方法时,我得到以下输出-
输出-
com.luv2code.aopdemo.dao.AccountDAO@3e0e1046
=======>>> Executing @Before Advice
com.luv2code.aopdemo.dao.AccountDAO@3e0e1046
正如你所看到的线条
System.out.println(accountDAO.toString());
和
System.out.println(this.toString());
给出同样的结果,before advice也执行成功。
默认情况下 toString()
定义为-
this.getClass().getName() + "@" + Integer.toHexString(this.hashCode())
但是当我显式打印出 getClass().getName() 时,结果不同
System.out.println(accountDAO.getClass().getName());
和
System.out.println(this.getClass().getName());
输出-
com.luv2code.aopdemo.dao.AccountDAO$$EnhancerBySpringCGLIB$eb61b6
=======>>> Executing @Before Advice
com.luv2code.aopdemo.dao.AccountDAO
两个class名字都不一样,不知道是哪种class名字。
此外,当我显式打印 hashCode()
时,结果也不同。
我对得到不同的结果感到困惑-
toString()
,当toString()
包括getClass().getName()
和hashCode()
getClass().getName()
hashCode()
为什么会有这些差异,我没有覆盖任何这些方法(在我这边),这是否与 AOP 代理有关?
请帮我解开这些疑惑。
编辑-
我也有一个非常奇怪的观察,当我修改
MainDemoApp.java
AccountDAO accountDAO = context.getBean("accountDAO", AccountDAO.class);
System.out.println(accountDAO.hashCode());
// call the business method
accountDAO.addAccount(accountDAO);
而AccountDAO.java
修改为-
public void addAccount(AccountDAO obj) {
System.out.println(this.hashCode() + " " + obj.hashCode());
}
现在 hashCode()
的结果是一样的,但是如果我不更改方法签名并在前一段代码上调用 hashCode()
,结果就不同了
谁也能解释一下吗?
欢迎来到 SO。请注意,在此平台上,最好只提出一个明确的问题,而不是提出很多问题。但我们也尽量对新手友善,所以我试着回答你的问题。虽然这有点多余,因为其他人已经在评论中回复了,但我也认为评论是评论,答案是答案,即答案应该这样写。可能这里的其他贡献者太忙了,无法写出全面的答案,所以我在这里接球。
System.out.println(accountDAO.toString());
And
System.out.println(this.toString());
give the same result
这是因为 accountDAO
是一个动态代理,而您正在对其应用 Spring AOP 方面。它正在将方法调用转发给它的委托(它正在代理的原始对象)。
But when I explicitly print out getClass().getName() the results are different
System.out.println(accountDAO.getClass().getName());
And
System.out.println(this.getClass().getName());
Output-
com.luv2code.aopdemo.dao.AccountDAO$$EnhancerBySpringCGLIB$eb61b6 =======>>> Executing @Before Advice com.luv2code.aopdemo.dao.AccountDAO
前者打印 CGLIB 代理的名称 class,后者打印目标 class 名称。
Also when I explicitly print
hashCode()
the results are different.
同样的原因:您正在打印代理与原始对象的哈希码。
Why are these differences there, I did not override any of these methods (At my end), does this has something related to AOP proxy?
嗯,在某种程度上你做到了。您应用了一个方面,导致代理创建。所以现在实际的 Spring bean 是一个代理,导致你上面描述的所有效果。从技术上讲,Spring 代理是一个 subclass(或接口实现,取决于您的设置以及您是否代理接口 ot class 类型)。代理保留对原始对象(其委托或目标对象)的引用,并使用附加功能对其进行装饰。这是一个众所周知的设计模式。 Spring 在整个框架中大量使用它。有关详细信息,请参阅
关于你的后续问题,根本原因和解释同上。一旦您了解 Spring AOP 使用动态代理并且相同的代理使用委托来实现 decorator pattern.
,这一切都非常简单和合乎逻辑。