Aspectj实现Spring中的动态代理。
1.首先我们新建设一个类和一个方法用来插入,就是所要插入的切面。
public
class
LogInterceptor {
public
void
before(){
System.
out
.println(
"method start!"
);
}
}
2.以及一个类方法用来被插入 就是在这个save方法前后加点代码。
@Component
(
"u"
)
public
class
UserDaoImp
implements
UserDAO{
public
void
save(User
u
) {
System.
out
.println(
"User saved!"
);
}
}
在这个save方法执行之前我们要插入before方法。
3.需要一个逻辑处理类,调用save方法
import
org.springframework.stereotype.Component;
import
javax.annotation.Resource;
@Component
(
"userService"
)
public
class
UserService {
@Resource
(name=
"u"
)
public
void
setUserDAO(UserDAO
userDAO
) {
this
.
userDAO
=
userDAO
;
}
public
void
add(User
user
){
this
.
userDAO
.save(
user
);
}
}
简单起见 只添加必要的方法。
这个类获得 user对象调用save方法把对象添加进去。但是同时我们注意到这个对象也是一个component,也就是说这一个bean 在初始化的时候会把这个类对象化放入bean容器。
4.配置文件bean.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:context
=
"http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation
=
"http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<
context:annotation-config
/>
<
context:component-scan
base-package
=
"com.harvey"
/>
<
aop:aspectj-autoproxy/>
</
beans
>
橘黄色的部分是我们需要的
5.在
LogInterceptor
类前添加 @Aspact和
@Component
以及在需要插入的方法前 添加@Before。
@Aspact 是为了声明这个类是一个切面,他下面的方法将要被插入其他方法代码中。
@Component 是为了什么呢,Spring在对两个方法结合的时候要求都是bean对象,所以这里的切面类也需要被component。
换句话说,如果任意一个类方法 不是在bean对象里,也就不受spring管束,那么Spring就不能对那个方法进行动态代理。
@Before 是放置在方法前声明这个方法会用来放置在其他方法前面的,这个其他方法就是@Before里面所指向的方法。
@Before
(
"execution(public void com.harvey.dao.impl.UserDaoImp.save(com.harvey.model.User))"
)
这句话的意思就是 在
com.harvey.dao.impl.UserDaoImp.save
这个save方法前插入下面的方法before
完整的代码:
import
org.aspectj.lang.annotation.Aspect;
import
org.springframework.stereotype.Component;
@Aspect
@Component
public
class
LogInterceptor {
@Before
(
"execution(public void com.harvey.dao.impl.UserDaoImp.save(com.harvey.model.User))"
)
public
void
before(){
System.
out
.println(
"method start!"
);
}
}
再次完整的解释下:
第一行:声明一个切面 通过@Aspect 注视;
第二行:声明这也是一个bean 通过@Component
第三行:一个类叫LogInterceptor
第四行:声明@Before以下的这个方法要被插入在 public void com.harvey.dao.impl.UserDaoImp.save(com.harvey.model.User))
这个方法的前面。
第五行:一个叫before的方法。
第六行:方法内容,这里就简单一个输出。
6.最后我们实现测试类
public
class
UserServiceTest {
@Test
public
void
testAdd()
throws
Exception{
//BeanFactory
ClassPathXmlApplicationContext
bf
=
new
ClassPathXmlApplicationContext(
"beans.xml"
);
UserService
service
= (UserService)
bf
.getBean(
"userService"
);
service
.add(
new
User());
bf
.destroy();
}
}