mg4155com > mg4155线路检测手机版 > 8落到实处柯里化,Java申明入门

原标题:8落到实处柯里化,Java申明入门

浏览次数:87 时间:2019-10-06

演示代码github地址

在Action操作中,关键正是Action中的exectue方法,可是此情势并从未request、session、application等对象作为参数,自然就不可能接纳那个目的来操作。平日能够利用多种艺术来获取那些指标:

一向聊本领!

在开辟中,不时会遇见 controller 之间跳转的气象,并且临时在跳转的时候须求把差别的参数字传送递过去,举个例子从controller a跳转到controller b,再从controller b到前面三个页面,并且把controller a里的多少比方StringListMap依旧指标传递到页面,等等类似地方。结合查找网络的材料以及和煦的试验,现总计如下。

在管理器科学中,柯里化(英语:Currying),又译为卡瑞化加里化,是把接受八个参数的函数转变来接受二个单一参数(最先函数的率先个参数)的函数,並且重临接受余下的参数而且回去结果的新函数的本事。这一个本领由克Rees多夫·Strachey以逻辑学家哈斯凯尔·Gary命名的,固然它是MosesSchönfinkel和戈特洛布·弗雷格发明的。

在Java中,要声Bellamy(Bellamy)个讲明很简短,只要你会利用接口,你就一定会选拔申明,以下是三个简练的注释的事例:

措施一、与Servlet解耦合的非IOC格局

获得的scope对象与容器非亲非故,通过ActionContext获取。

package test002;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionSupport;import java.util.Map;/** * Created by yangcs on 2017/1/19. * 通过与servlet解耦和的非IOC方式来获取scope对象 */public class ScopeAction extends ActionSupport{ private String name; private String req; private String sess; public String getReq() { return req; } public void setReq(String req) { this.req = req; } public String getSess() { return sess; } public void setSess(String sess) { this.sess = sess; } public String getApp() { return app; } public void setApp(String app) { this.app = app; } private String app; public String getName() { return name; } public void setName(String name) { this.name = name; } ActionContext context; //这个是解耦和的关键 Map request; Map session; Map application; @Override public String execute(){ context = ActionContext.getContext(); request =  context.get("request"); session =context.getSession(); application = context.getApplication(); request.put("req",req); session.put("sess",sess); application.put("app",app); return SUCCESS; }}

分析:通过ActionContext的getContext静态方法得到ActionContext对象,然后ActionContext对象调用get方法来获取一个存储在request范围中的对象。我们使用el或通过request.getAttribute这样的方式均可以获取对象值,这说明了这些Map request对象实际是存储在request范围内的对象。

描述

代办情势是常用的java设计格局,代理类首要承担为委托类预管理新闻、过滤音讯、把新闻转载给委托类,以及以后拍卖音信等。代理类与委托类之间经常会设有涉嫌关系,一个代理类的目的与一个委托类的目的关联,代理类的靶子自笔者并不确实兑现劳务,而是通过调用委托类的对象的相干办法,来提供一定的服务。

8落到实处柯里化,Java申明入门。代理类能够分为三种。静态代理:由程序猿创制或特定工具自动生陈哲超代码,再对其编译。在程序运转前,代理类的.class文件就已经存在了。动态代理:在程序运转时,运用反射机制动态创立而成。

简单来说,意思即是 你不用去做,让别人代替你去做!

先讲讲怎么通过静态代理完结具体育赛职业

业务描述在吃中饭此前洗手,在吃午饭之后擦嘴

注: 本文实例均在springmvc框架下,其余架构自行调度。

在函数式编制程序中,函数的概念跟数学中等高校函授数的概念是同一的,类似于“映射”。高阶函数和柯里化是函数式编制程序的天性。

public @interface Table{ // add code to yourself}

方法二、与Servlet解耦合的IOC情势

package test002;import com.opensymphony.xwork2.ActionSupport;import org.apache.struts2.interceptor.ApplicationAware;import org.apache.struts2.interceptor.RequestAware;import org.apache.struts2.interceptor.SessionAware;import java.util.Map;/** * Created by yangcs on 2017/1/19. * 与servlet解耦和的IOC方式(依赖于struts框架来实现对象的实例化,依赖注入、控制反转)获取scope对象 */public class ScopeAction02 extends ActionSupport implements RequestAware,SessionAware,ApplicationAware{ private Map request; private Map session; private Map application; @Override public void setApplication(Map<String, Object> map) { application = map; } @Override public void setRequest(Map<String, Object> map) { request = map; } @Override public void setSession(Map<String, Object> map) { session = map; } private String req; private String sess; private String app; public String getReq() { return req; } public void setReq(String req) { this.req = req; } public String getSess() { return sess; } public void setSess(String sess) { this.sess = sess; } public String getApp() { return app; } public void setApp(String app) { this.app = app; } @Override public String execute(){ request.put("req",req); session.put("sess",sess); application.put("app",app); System.out.println("reqMap为:"+request); return "success"; }}

说明:此方法其实和方式一很相似,只是在方式一中我们需要手动的为Map request赋值,但是在方式二中它是通过实现接口,在重写接口中的方法中完成对Map requset的赋值,所以称之IOC方式。 强调:方式二是开发中主要用的方式,应重点掌握 
package staticProxy; /** * @author:稀饭 * @time:下午12:23:19 * @filename:EatLaunch.java */public interface EatLunch { public void eat();} package staticProxy; /** * @author:稀饭 * @time:下午12:21:31 * @filename:EatLaunch.java */public class EatLaunchImpl implements EatLunch{ @Override public void eat() { // TODO Auto-generated method stub System.out.println; } }//代理类package staticProxy; /** * @author:稀饭 * @time:下午12:27:27 * @filename:EatLunchProxy.java */public class EatLunchProxy implements EatLunch { private EatLunch eatLunch; public EatLunchProxy(){ eatLunch = new EatLaunchImpl(); } public void before() { System.out.println; } public void after() { System.out.println; } /** * @Title: eat * @Description: TODO */ @Override public void eat() { // TODO Auto-generated method stub before(); eatLunch.eat(); after(); }}package staticProxy;/** * @Author 稀饭 * @DATE 2017/2/512:40 */public class TestDemo {public static void main(String[] args){EatLunch eatLunch = new EatLunchProxy();eatLunch.eat();}}

跳转格局

应用重返 String 的秘籍: return "forward:Xxx.action";

@RequestMappingpublic String logout(ModelMap model, RedirectAttributes attr) { return "forward:test.action";}

设若使用ModelAndView方式: return new ModelAndView("forward:/tolist");

:此后,都是回到String的不二秘诀来描述。

@RequestMappingpublic String logout(ModelMap model, RedirectAttributes attr) { return "redirect:test.action";}

forward是伸手转载,是劳动器端行为,约等于叁遍呼吁,地址栏的 U福特ExplorerL 不会变动。redirect是呼吁重定向,是顾客端表现,相当于四回呼吁,地址栏的 U传祺L 会改动。

对于柯里化来讲,首先我们来举个栗子,先定义那样三个函数

聪慧的你一定会发掘,把接口形成表明只供给再interface前增添贰个@符号就能够了.

艺术三、与Servlet耦合的非IOC格局

package test002;import com.opensymphony.xwork2.ActionSupport;import org.apache.struts2.ServletActionContext;import javax.servlet.ServletContext;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;/** * Created by yangcs on 2017/1/19. * 与servlet相耦合的非IOC方式获取scope对象 * 这种方式获取的为纯粹的Scope对象,它与容器相关,这些Scope对象操作性更强 */public class ScopeAction03 extends ActionSupport{ private String req; private String sess; private String app; public String getReq() { return req; } public void setReq(String req) { this.req = req; } public String getSess() { return sess; } public void setSess(String sess) { this.sess = sess; } public String getApp() { return app; } public void setApp(String app) { this.app = app; } HttpServletRequest request; HttpSession session; ServletContext application; @Override public String execute(){ request = ServletActionContext.getRequest(); //这里,就是耦合了servlet了 session = request.getSession(); application = ServletActionContext.getServletContext(); request.setAttribute("req",req); session.setAttribute("sess",sess); application.setAttribute("app",app); return SUCCESS; }}

此方法获取的纯粹的Scope对象,它与容器相关,这些Scope对象可操作性更强。

从上述的源码能够见到,假诺工作场景是吃早饭、吃完饭也要洗手、擦嘴的话,则供给多提供多少个代理类,那样会促成代码不雅观并且多,那么什么样消除呢?学完动态代理之后您就精晓了啊!

动态代理能够分成三种:JDK动态代理和CGLIB动态代理

如何区分JDK动态代理不可能代理八个尚未接口的类,而那也是CGLIB动态代理现身的缘由了。

JDK动态代理的demo,源码如下

跳转时数据的传递

return "redirect:/login.action?name="+ name;

login.action:

@RequestMapping public String login(HttpServletRequest request, ModelMap model, RedirectAttributes attr ) { String name = request.getParameter; model.addAttribute("name",name); return "login"; }

然后在login.html接收,用${name}即可。

拼接url传参的弱项:

  • 参数满含普通话字符的话,轻松并发难题
  • 不能

RedirectAttributes 是 Spring mvc 3.1 版本之后出来的一个效能,特地用于重定向之后还是能带参数跳转的的工具类。它有三种带参的不二秘诀:

第一种:redirectAttributes.addAttributie("prama",value);

redirectAttributes.addAttribute("prama1",value1);redirectAttributes.addAttribute("prama2",value2);return:"redirect:/path/list" 

这种艺术也正是在重定向链接地址追加传递的参数:return:"redirect:/path/list?prama1=value1&prama2=value2(直接扩充参数会将传递的参数揭破在链接的地址上,特其他不安全,慎用)

第二种:redirectAttributes.addFlashAttribute("prama",value);

redirectAttributes.addFlashAttribute("prama1",str);redirectAttributes.addFlashAttribute("prama2",list);redirectAttributes.addFlashAttribute("prama3",map);return:"redirect:/path/list.jsp" ;

此方法遮掩了参数,链接地址上不直接揭破,可是能且不得不在重定向的页面上取得prama的值。其规律是参数放到了sessionsession在跳转之后立刻移除对象。要是重定向到贰个controller,是取不到该prama的值的。

如上所述,controller里面跳转然后把参数字传送到前台页面,这种格局完成起来困难不谄媚,对于数据传递以及前台页面包车型大巴摄取呈现来讲不是很要好,其实能够换到用ajax主意来做,调用后台数据更是灵敏何况有个别刷新作用也尤其和睦。But,二种格局,种种抉择。

f = *z

Target注明证明了Annotation所修饰对象的限定,它可携家带口的参数可枚举如下:

方式四、与Servlet耦合的IOC方式

package test002;import com.opensymphony.xwork2.ActionSupport;import org.apache.struts2.interceptor.ServletRequestAware;import org.apache.struts2.util.ServletContextAware;import javax.servlet.ServletContext;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;/** * Created by yangcs on 2017/1/19. * 与servlet耦合的情况下使用IOC获取scope对象 */public class ScopeAction04 extends ActionSupport implements ServletRequestAware,ServletContextAware{ HttpServletRequest request; HttpSession session; ServletContext application; @Override public void setServletRequest(HttpServletRequest httpServletRequest) { request = httpServletRequest; } @Override public void setServletContext(ServletContext servletContext) { application = servletContext; } private String req; private String sess; private String app; public String getReq() { return req; } public void setReq(String req) { this.req = req; } public String getSess() { return sess; } public void setSess(String sess) { this.sess = sess; } public String getApp() { return app; } public void setApp(String app) { this.app = app; } @Override public String execute(){ request.setAttribute("req",req); session = request.getSession(); session.setAttribute("sess",sess); application.setAttribute("app",app); return SUCCESS; }}
package dynamicProxy;/** * @author:稀饭 * @time:上午11:33:09 * @filename:Hello.java */public interface Hello { public void say(String name);}package dynamicProxy;/** * @author:稀饭 * @time:上午11:48:43 * @filename:HelloImpl.java */public class HelloImpl implements Hello { /** @Title: say * @Description: TODO * @param name */ @Override public void say(String name) { // TODO Auto-generated method stub System.out.println("dynamicProxy.Hello "+name+"!"); }}package dynamicProxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;/** * @author:稀饭 * @time:上午11:26:04 * @filename:DynamicPrxy.java */public class DynamicProxy implements InvocationHandler { private Object target; public DynamicProxy(Object target) { this.target = target; } /** * @Title: invoke * @Description: TODO * @param proxy * @param method * @param args * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub before(); Object result = method.invoke(target, args); after(); return result; } //同样的业务操作 public void before() { System.out.println("this is before function"); } //同样的业务操作 public void after() { System.out.println("this is after function"); } @SuppressWarnings("unchecked") public <T> T getProxy() { return  Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces; }}package dynamicProxy;/** * @author:稀饭 * @time:上午11:32:56 * @filename:TestDemo.java */public class TestDemo { /** @描述: * @时间:上午11:32:56 * @开发者:稀饭 * @测试: * @param */ public static void main(String[] args) { // TODO Auto-generated method stub DynamicProxy dy = new DynamicProxy(new HelloImpl; Hello hello = dy.getProxy(); hello.say; }}

当x是叁个常量时,比如x=4,能够用叁个新的函数来代替

public enum ElementType { /**类|接口|枚举类型*Class, interface (including annotation type), or enum declaration */ TYPE, /**成员变量 包括枚举常量*Field declaration (includes enum constants)*/ FIELD, /** 方法声明 Method declaration */ METHOD, /** 形参声明 Formal parameter declaration */ PARAMETER, /** 构造函数 Constructor declaration */ CONSTRUCTOR, /** 局部变量 Local variable declaration */ LOCAL_VARIABLE, /** Annotation type declaration */ ANNOTATION_TYPE, /** 包 Package declaration */ PACKAGE, /** * Type parameter declaration * * @since 1.8 java 1.8 以上新增支持 * @hide 1.8 */ TYPE_PARAMETER, /** * Use of a type * @since 1.8 java 1.8 以上新增支持 * @hide 1.8 */ TYPE_USE}

附:用于测量检验的寻访页面及结果体现页面:

struts.xml配置文件:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"><struts> <package name="test002" namespace="/" extends="struts-default"> <action name="Action003" > <result name="success">/JSP/scope01.jsp</result> </action> <action name="Action004" > <result name="success">/JSP/scope01.jsp</result> </action> <action name="Action005" > <result name="success">/JSP/scope01.jsp</result> </action> <action name="Action006" > <result name="success">/JSP/scope01.jsp</result> </action> </package></struts>

输入参数页面:

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>scope</title></head><body>本页面展示在action中获取scope对象<br><br><form method="get" action="Action003.action"> 这个表单是使用与servlet解耦和的非IOC方式来获取scope对象<br> request:<input type="text" name="req"/><br> session:<input type="text" name="sess"/><br> appliaction:<input type="text" name="app"/><br> <input type="submit"/></form><form method="get" action="Action004.action"> 这个表单是使用与servlet解耦和的IOC方式来获取scope对象<br> request:<input type="text" name="req"/><br> session:<input type="text" name="sess"/><br> appliaction:<input type="text" name="app"/><br> <input type="submit"/></form><form method="get" action="Action005.action"> 这个表单是使用与servlet耦和的非IOC方式来获取scope对象<br> request:<input type="text" name="req"/><br> session:<input type="text" name="sess"/><br> appliaction:<input type="text" name="app"/><br> <input type="submit"/></form><form method="get" action="Action006.action"> 这个表单是使用与servlet耦和的IOC方式来获取scope对象<br> request:<input type="text" name="req"/><br> session:<input type="text" name="sess"/><br> appliaction:<input type="text" name="app"/><br> <input type="submit"/></form></body></html>

获取参数字展现示页面:

<%-- Created by IntelliJ IDEA. User: yangcs Date: 2017/1/19 To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head> <title>scope01</title></head><body> request:${requestScope.req}<br> session:${sessionScope.sess}<br> application:${applicationScope.app}<br></body></html>

源码分析:DynamicProxy达成了InvocationHandler接口,必得兑现invoke方法,在该措施中央直属机关接通过反射invoke method,在调用前后分别处理before和after,最终将result重返。而在Test德姆o中hello调用say的时候,由于Hello已经被“代理”了,所以在调用say函数的时候实在是调用invoke函数,而在invoke函数中首先达成了before函数才落实Object result = method.invoke(target, args),这一句实在是调用say函数,而后才促成after函数,用吃饭前洗手、吃就餐之后擦嘴的事业来套的话用了动态代理是否只要求叁个代理类就能够了?对的!

CGlib动态代理的demo,源码如下

f=g=*z

本文由mg4155com发布于mg4155线路检测手机版,转载请注明出处:8落到实处柯里化,Java申明入门

关键词:

上一篇:没有了

下一篇:没有了