Spring的AOP(切面)编程 测试示例DEMO 面向过程 面向对象 面向切面
目前我所知道的编程大概有以下三种了:
1、面向过程
最初知道的就是面向过程的编程
打个比喻:比如吧,我要炒菜:怎么炒呢?先把菜洗干净,然后把锅放放到煤气灶上,然后开火,然后把菜放进锅里。。。。。。。
面向过程简单的 一句话就是从上往下依次执行
2、面向对象
后来学习java就知道了面向对象
还是来个比喻吧:比如还是我要炒菜:菜就是一个对象,锅也是一个对象,煤气灶也是一个对象,现在我直接拿起锅川开始炒就是,我无需关心菜怎么洗的,锅怎么放的,因为这些对象他自己知道怎么洗怎么放
3、面向切面
再后来逐渐连接到了spring的AOP——面向切面编程
那这是什么意思呢
还是以炒菜为例:炒菜的时候,油烟问题怎么解决了,让抽油烟机来处理撒,但是抽油烟机处理油烟的时候影不影响您炒菜?不影响的。你自己还是炒你的菜,抽油烟机自己处理这个油烟问题
这就是面向切面编程,他是对面向对象的一个补充
那么放到程序中怎么实现呢
比如一个类中的方法,我们想在这个方法之前或之后或方法前后执行一些操作,这就是和上面的例子很像了吗?
则个方法就好比你在炒菜,方法之前执行的操作就好比处理油烟问题
那么下面我们就用java代码,用我实际项目中的代码来为大家展示以下切面编程
一共大概需要3三步:
1、首先我们创建一个类,普通的类
@Service("sersiu") public class SerUser implements SerIterUser{ @Resource(name="daologinorgister") private LoginOrRegisterIter lor; @Override public Map<String, Object> login(String username, String password,int groupuser,HttpSession session,String IpAddress) { userloginpo ulp; List<?> list = lor.user(username, password, groupuser); ulp = (list == null?null:(userloginpo)list.get(0)); //我们需要在这个方法之后执行一些操作,比如,写入日志等操作,这些操作不是写在这里的 String datestr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); if(ulp == null){ session.setAttribute("LoginAOP", datestr+"\t"+IpAddress+"\t"+username+"\t"+"Login\t"+"false"); return null; }else{ HashMap<String, Object> map = new HashMap<String, Object>(); map.put("username", username); map.put("userid", ulp.getUserid()); session.setAttribute("LoginAOP", datestr+"\t"+IpAddress+"\t"+username+"\t"+"Login\t"+"true"); return map; } } public void register(){ } }
这个类是注册和登录的service类。我们需要在登录方法,即login方法运行完之后去执行一些其他的额外信息,比如写入日志,而且不影响网站其他的业务处理,比如接下来跳转到会员页读取数据,这些都不受影响
2、开始创建一个切面类
切面类主要定义了切入点等信息
@Aspect @Component("apbean") public class AdviceLoginRegister { /* * 定义切入点 */ @Resource(name="uic") private UserIpCount uic; @Pointcut("execution(* springMVC.NLoveB.service.suser.iter.SerIterUser.login(..))") public void LoginLog(){ System.out.println("记录登录日志,判断后将需要写入的数据写入,否则不写入"); } @Pointcut("execution(* springMVC.NLoveB.service.suser.impl.SerUser.register(..))") public void RegisterLog(){ System.out.println("记录注册日志,判断将需要写入的数据写入,否则不写入,判断是否发邮件,否则不发送"); } //业务执行之后的操作 @After(value="LoginLog()") public void LLog(){ RequestAttributes ra = RequestContextHolder.getRequestAttributes(); ServletRequestAttributes sra = (ServletRequestAttributes)ra; HttpServletRequest request = sra.getRequest(); HttpSession session = request.getSession(); String LoginAOPStr = (String) session.getAttribute("LoginAOP"); //时间,ip,姓名,登录/注册,true(成功)(length=5) LogWriterFile.writerlog(LoginAOPStr); } } @After(value="RegisterLog()") public void RLog(){ } }
说明以下:
@Aspect注解表示这是一个切面类
@Pointcut注解表示切入点,比如本例表示SerIterUser的login方法
@After表示执行为login方法之后
当然您也猜到了还有@Before表示执行login方法之前
比如上面代码中的这个方法
//业务执行之后的操作
@After(value="LoginLog()")
public void LLog(){
}
表示执行login方式之后就执行这个LLog方法
After里面的参数确定了切入点是login,这个参数是个方法LoginLog(),而这个方法就定义了切入点。
在spring里获得session
下面的代码是spring里面获得当前session的方法,大家可以参考下
ServletRequestAttributes sra = (ServletRequestAttributes)ra;HttpServletRequest request = sra.getRequest();
HttpSession session = request.getSession();
配置applicationContext.xml只需要添加一句代码
<aop:aspectj-autoproxy />
启动aspectj
对了,这里需要注意一下:在第二点代码中的切入点,是一个接口方式
就是说SerIterUser是个接口类:springMVC.NLoveB.service.suser.iter.SerIterUser
如果不是接口,那您在<aop:aspectj-autoproxy />里面应该加上
proxy-target-class="true"
即
<aop:aspectj-autoproxy proxy-target-class="true" />
最后的测试很简单,当有用户进行登录的时候,执行完login方法后,他就会自动执行我们配置好的AOP里面的程序
爆款云服务器s6 2核4G 低至0.46/天,具体规则查看活动详情