在这个炎炎夏日,我渴望透心凉,那么你也要来一瓶吗?
从来没人告诉我们做一件事养成好的习惯有多么至关重要,只是告诉我们这个对那个不对,也许事与愿违,但我们都想往好的方向发展。那么今天我们就要从好的方面开始做起。
在做一个项目的时候,首先明确分包是一个锻炼统筹能力的好的开端,从模仿中我们可以总结-归纳-演绎,直至达到巅峰,没错盖世神功就是这样炼成的。
java项目的四层体系分别是model层,dao层,service层,controller层,从四层体系中来接触aop怎么使用
首先在model包下我们创建User类
public class User {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User: id = " + id
+ " name = " + name;
}
}
在dao包下面创建数据访问层IUserDao接口
//数据访问层
public interface IUserDao {
void add(User user);
}
创建UserDao使用repository注解
//等于完成了<bean id="userDao" class="com.spring.dao.UserDao"/>
//@Repository一般用于DAO的注入
@Repository
public class UserDao implements IUserDao {
@Override
public void add(User user) {
System.out.println("add:"+ user);
}
}
在service包下创建业务层IUserService接口
public interface IUserService {
void add(User user);
}
创建UserService使用service注解 持有IUserDao 自动装配
// 业务层一般使用service
@Service
public class UserService implements IUserService {
@Autowired
private IUserDao userDao;
@Override
public void add(User user) {
userDao.add(user);
}
}
在controller包下创建UserController
//控制层使用controller注解 Scope定义为多例,默认单例
@Controller
@Scope("prototype")
public class UserController {
private User user;
@Autowired
private IUserService userService;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public void add(){
userService.add(user);
}
}
接下来重点来了,创建PrintLog类使用component注解,来展示我们的AOP使用
//打印日志记录
@Component
public class PrintLog {
public void start(JoinPoint joinPoint){
// 执行的对象
System.out.println(joinPoint.getTarget());
// 执行的方法名
System.out.println(joinPoint.getSignature().getName());
Logger.i("开始打印");
}
public void end(){
Logger.i("结束打印");
}
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Logger.i("around中加入日志");
// 执行程序
proceedingJoinPoint.proceed();
Logger.i("结束around");
}
}
这里我创建了Logger工具类
public class Logger {
public static void i(String s){
System.out.println("=========="+s);
}
}
创建beans.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<!--打开Spring的Annotation支持-->
<context:annotation-config/>
<!--设定Spring找Annotation-->
<context:component-scan base-package="com.spring"/>
<!-- 例如定义切入点表达式 execution(* com.sample.service.impl..*.*(..))
整个表达式可以分为五个部分:
1、execution(): 表达式主体。
2、第一个*号:表示返回类型,*号表示所有的类型。
3、包名:表示需要拦截的包名,(“.*”表示包下的所有类) 而“..*”表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。
4、其中第二个*号:是表示类名。
5、*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。-->
<aop:config>
<!--定义切面-->
<aop:aspect id="testAspect" ref="printLog">
<!--要加入aspect的位置-->
<aop:pointcut id="testPointCut" expression="execution(* com.spring.dao.*.add*(..))"/>
<!--在之前加入-->
<aop:before method="start" pointcut-ref="testPointCut"/>
<!--环绕-->
<aop:around method="around" pointcut-ref="testPointCut"/>
<!--在之后加入-->
<aop:after method="end" pointcut-ref="testPointCut"/>
</aop:aspect>
</aop:config>
</beans>
编写测试代码:
public class Main {
// public static void main(String[] args) {
// System.out.println("Hello World!");
// }
private BeanFactory factory = new ClassPathXmlApplicationContext("beans.xml");
@Test
public void testUserAOP(){
UserController userController = factory.getBean("userController",UserController.class);
User user = new User();
user.setId(100);
user.setName("nickName");
userController.setUser(user);
userController.add();
}
}
输出信息:
com.spring.dao.UserDao@1887735
add
==========开始打印
==========around中加入日志
add:User: id = 100 name = nickName
==========结束around
==========结束打印
PS:在四层体系中controller调用service,service调用dao,dao又持有model原型,中间穿插切面编程,只需要在beans.xml中配置一下,一点都不会破坏代码的完整性,当然我们使用注解还简化了一部分代码,实乃神兵利器。