[SpringMVC] SpringMVC

2024-05-09 05:08
文章标签 springmvc spring java

本文主要是介绍[SpringMVC] SpringMVC,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

RequestMapping注解

  • SpringMVC使用@RequestMapping注解为控制器指定可以处理哪些URL请求
  • 在控制器的类定义及方法定义处都可标注
    • 类定义处:提供初步的请求映射信息,相对于WEB应用的根目录
    • 方法定义处:提供进一步的细分映射信息,相对于类定义处的URL,若类定义处未标注@RequestMapping,则方法标记处的URL相当于WEB应用的根目录
  • DispatchServlet截获请求后,就通过控制器上@RequestMapping提供的映射信息确定请求所对应的处理方法。
  • @RequestMapping除了可以使用请求URL映射请求外,还可以使用请求方法、请求参数及请求头映射请求
  • @RequestMapping的value、method、params和heads分别表示请求URL、请求方法、请求参数及请求头的映射条件,它们之间是与的关系,联合使用多个条件可以让请求映射更加精确化
  • params和headers支持简单的表达式:
    • param1:表示请求必须包含名为param1的请求参数
    • !param1:表示请求不能包含名为param1的请求参数
    • param1!=value1:表示请求包含名为param1的请求参数,但其值不能为value1
    • {“param1=value1”, “param2”}:表示请求包含名为param1和param2的两个请求参数,且param1参数的值必须为value1
  • Ant风格资源地址支持3种匹配符:
    • ?:匹配文件名中的一个字符
    • *:匹配文件名中的任意字符
    • **:匹配多层路径
  • @RequestMapping还支持Ant风格的URL:
    • /user/*/createUser:匹配/user/aaa/createUser、/user/bbb/createUser等URL
    • /user/**/createUser:匹配/user/createUser、/user/aaa/bbb/createUser等URL
    • /user/createUser??:匹配/user/createUseraa、/user/createUserbb等URL

@PathVariable注解

@PathVariable映射URL绑定的占位符,通过@PathVariable可以将URL中占位符参数绑定到控制器处理方法的入参中:URL中的{xxx}占位符可以通过@PathVariable("xxx")绑定到操作方法的入参中。

@RequestMapping("/testPathVariable/{id}")
public String testPathVariable(@PathVariable(value="id") Integer id) {System.out.println("testPathVariable: " + id);return SUCCESS;
}

REST

HTTP协议里面,四个操作方式的动词:GET、POST、PUT、DELETE,它们分别对应4种基本操作:GET用来获取资源,POST用来新建资源,PUT用来更新资源,DELETE用来删除资源。

示例:

  • /order/1 HTTP GET:得到id=1的order
  • /order/1 HTTP DELETE:删除id=1的order
  • /order/1 HTTP PUT:更新id=1的order
  • /order HTTP POST:新增order

浏览器form表单只支持GET和POST请求,而DELETE、PUT等method并不支持,Spring添加了一个过滤器HiddenHttpMethodFilter,可以将这些请求转换为标准的http方法,使得支持GET、POST、PUT与DELETE请求。

需在web.xml中配置HiddenHttpMethodFilter,例如:

<!--配置org.springframework.web.filter.HiddenHttpMethodFilter:可以把POST请求转为DELETE或PUT请求-->
<filter><filter-name>hiddenHttpMethodFilter</filter-name><filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping><filter-name>hiddenHttpMethodFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>

相应的index.jsp如下:

<form action="testRest/1" method="post"><input type="hidden" name="_method" value="PUT"/><input type="submit" value="TestRest PUT"/>
</form>
<br><br>
<form action="testRest/1" method="post"><input type="hidden" name="_method" value="DELETE"/><input type="submit" value="TestRest DELETE"/>
</form>
<br><br>
<form action="testRest" method="post"><input type="submit" value="TestRest POST"/>
</form>
<br><br>
<a href="testRest/1">Test Rest GET</a>
<br><br>

相应的处理器方法如下:

@RequestMapping(value = "/testRest/{id}", method = RequestMethod.PUT)
public String testRestPut(@PathVariable("id") Integer id) {System.out.println("testRest PUT: " + id);return SUCCESS;
}@RequestMapping(value = "/testRest/{id}", method = RequestMethod.DELETE)
public String testRestDELETE(@PathVariable("id") Integer id) {System.out.println("testRest DELETE: " + id);return SUCCESS;
}@RequestMapping(value = "/testRest", method = RequestMethod.POST)
public String testRest() {System.out.println("testRest POST");return SUCCESS;
}@RequestMapping(value = "/testRest/{id}", method = RequestMethod.GET)
public String testRest(@PathVariable("id") Integer id) {System.out.println("testRest GET: " + id);return SUCCESS;
}

使用@RequestParam绑定请求参数值

在处理方法入参处使用@RequestParam可以把请求参数传递给请求方法,其具有两个属性:value表示参数名,required表示是否必须,默认为true,表示请求参数中必须包含对应的参数,若不存在,将抛出异常!

@RequestMapping(value = "/testRquestParam")
public String testRquestParam(@RequestParam(value = "username") String username, @RequestParam(value = "age") Integer age) {System.out.println("testRquestParam, username: " + username + " age: " + age);return SUCCESS;
}

使用POJO对象绑定请求参数值

SpringMVC会按请求参数名和POJO属性名进行自动匹配,自动为该对象填充属性值,支持级联属性!

@RequestMapping("/testPojo")
public String testPojo(User user) {System.out.println("testPojo: " + user);return SUCCESS;
}

相应的表单文件为:

<form action="testPojo" method="post">username: <input type="text" name="username"/><br>password: <input type="password" name="password"/><br>email: <input type="text" name="email"/><br>age: <input type="text" name="age"/><br>city: <input type="text" name="address.city"/><br>province: <input type="text" name="address.province"/><br><input type="submit" value="submit"/>
</form>

使用Servlet API作为入参

MVC的Handler方法可以接收以下这些类型的ServletAPI参数:

  • HttpServletRequest
  • HttpServletResponse
  • HttpSession
  • java.security.Principal
  • Locale
  • InputStream
  • OutputStream
  • Reader
  • Writer
@RequestMapping("/testServletAPI")
public void testServletAPI(HttpServletRequest request, HttpServletResponse response, Writer out) throws IOException {System.out.println("testServletAPI, " + request + ", " + response);out.write("hello Spinrmvc");
}

处理模型数据

SpringMVC提供了以下几种方法输出模型数据:

  • ModelAndView:处理方法返回值类型为ModelAndView,方法体即可通过该对象添加模型数据
  • Map和Model:入参为Model、ModelMap或Map时,处理方法返回时,Map中的数据会自动添加到模型中
  • @SessionAttributes:将模型中的某个属性暂存到HttpSession中,以便多个请求之间可以共享这个属性
  • @ModelAttribute:方法入参标注该注解后,入参的对象就会放到数据模型中

ModelAndView

控制器处理方法的返回值如果是ModelAndView,则其既包含视图信息,又包含模型数据信息。

  • 添加模型数据
    • ModelAndView addObject(String attributeName, Object attributeValue)
    • ModelAndView addAllObject(Map<String, ?> modelMap)
  • 设置视图
    • void setView(View view)
    • void setViewName(String viewName)
/*** 目标方法的返回值可以是ModelAndView类型,其中可以包含视图和模型信息* SpringMVC会把ModelAndView的model中的数据放到request域对象中* @return*/
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView() {ModelAndView modelAndView = new ModelAndView(SUCCESS);modelAndView.addObject("time", new Date());return modelAndView;
}

正如上面注释所述,通过源码分析可知,添加到ModelAndView中的数据最终放到到了request请求域中。

Map以及Model

SpringMVC在内部使用了一个Model接口存储模型数据,具体步骤为:

  • SpringMVC在调用方法前会创建一个隐含的模型对象作为模型数据的存储数据
  • 如果方法的入参为Map或Model类型,SpringMVC会将隐含模型的引用传递给这些入参,在方法体内,开发者可以通过这个入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据。
/*** 目标方法可以添加到Map(实际上也可以是Model或ModelMap)类型的参数* @param map* @return*/
@RequestMapping("/testMap")
public String testMap(Map<String, Object> map) {map.put("names", Arrays.asList("Tom", "Jerry", "Mike"));return SUCCESS;
}

@SessionAttributes

若希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注一个@SessionAttributes,SpringMVC将在模型中对应的属性存到HttpSession中。

@SessionAttributes除了可以通过属性名指定需要放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中。

  • @SessionAttributes(types=User.class)会将隐含模型中所有类型为User.class的属性添加到会话中
  • @SessionAttributes(value={"user1", "user2"})
  • @SessionAttributes(types={User.class, Dept.class})
  • @SessionAttributes(value={"user1", "user2"}, types={Dept.class})
@RequestMapping("/testSessionAttribute")
public String testSessionAttribute(Map<String, Object> map) {User user = new User("Tom", "123456", "tom@gmail.com", 15);map.put("user", user);map.put("school", "initialsoft");return SUCCESS;
}

@ModelAttribute

先看下面这个例子:

/*** 1. 有@ModelAttribute标记的方法会在每个目标方法执行之前被SpringMVC调用* 2. @ModelAttribute注解也可以修饰目标方法POJO类型的入参,其value属性值中具有如下作用:* 1) SpringMVC会使用value属性值在implicitModel中查找对应的对象,若存在则会直接传入到目标方法的入参中* 2)SpringMVC会以value为key,POJO类型的对象为value存入到request中* @param id* @param map*/
@ModelAttribute
public void getUser(@RequestParam(value = "id", required = false) Integer id, Map<String, Object> map) {if (id != null) {User user = new User(1, "Tom", "123456", "tom@gmail.com", 12);map.put("user", user);System.out.println("从数据库中获取一个对象: " + user);}
}/*** 1. 执行@ModelAttribue注解修饰的方法:从数据库中取出对象,将对象放入到了Map中,键为user* 2. SpringMVC从Map中取出User对象,并把表单的请求参数赋给该User对象的对应属性* 3. SpringMVC把上述对象传入目标方法的参数* 注意:在ModelAttribute修饰的方法中放入到Map时的键需要和目标方法入参类型的第一个字母小写的字符串一致** 源代码分析的流程:* 1. 调用@ModelAttribute注解修饰的方法,实际上把@ModelAttribute修饰的方法中Map中的数据放到implicitModel中* 2. 解析请求处理器的目标参数,实际上该目标参数来自于WebDataBinder的target属性* 1)创建WebDataBinder对象:* ①. 确定objectName属性:若传入的attrName属性值为空的话则objectName为类名第一个字母小写* 注意:attrName,若目标方法的pojo属性使用了@ModelAttribute来修饰,则attrName值即为@ModelAttribute的value属性值* ②. 确定target属性* > 在implicitModel中查找attrName对应的属性值,若存在,ok* > 若不存在,则验证当前Hadnler是否使用了@SessionAttributes进行修饰,若使用了@SessionAttributes修饰,则尝试从Session中获取attrName所对应的属性值* 若Session中没有对应的属性值,则抛出了异常* > 若Handler没有使用@SessionAttribute进行修饰,或@SessionAttribute中没有attrName键则通过反射创建了pojo对象* 2) SpringMVC把表单的请求参数赋给了WebDataBinder的target对应的属性* 3) SpringMVC会把WebDataBinder的attrName和target给到implicitModel* 4) 把WebDataBinder的target作为参数传递给目标方法的入参* @param user* @return*/
@RequestMapping("/testModelAttribute")
public String testModelAttribute(User user) {System.out.println("修改: " + user);return SUCCESS;
}
SpringMVC确定目标方法POJO类型入参的过程
  • 确定一个key
    • 若目标方法的POJO类型的参数木有使用@ModelAttribute作为修饰,则key为POJO类名第一个字母小写
    • 若使用了@ModelAttribute来修饰,则key为@ModelAttribute注解的value属性值
  • 在implicitModel中查找key对应的对象,若存在,则作为入参传入
    • 若在@ModelAttribute标记的方法中在Map中保存过且key和第一步中确定的key一致则会获取到
  • 若不存在key对应的对象则检查当前的Handler是否使用@SessionAttributes注解进行修饰,若使用了该注解,且@SessionAttributes注解的value属性值中包含了key则会从HttpSession中来获取key所对应的value值,若存在则直接传入到目标方法的入参中,若不存在则将抛出异常
  • 若Handler没有标识@SessionAttributes注解或@SessionAttributes注解的value值中不包含key,则会通过反射来创建POJO类型的参数,然后传入为目标方法的参数
  • SpringMVC会把key和POJO类型的对象保存到implicitModel中进而会保存到request中

视图和视图解析器

  • 无论目标方法返回时String、ModelAndView或者View,SpringMVC都会转换成ModelAndView对象

  • SpringMVC借助视图解析器(ViewResolver)得到最终的视图对象(View),最终的视图可以是JSP,也可能是Excel、JFreeChart等各种表现形式的视图

  • 若项目中使用了JSTL,则SpringMVC会自动把视图由InternalResourceView转为JstlView

  • 若使用JSTL的fmt标签则需要在SpringMVC的配置文件中配置国际化资源文件

    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
    <property name="basename" value="i18n"></property>
    </bean>
  • 若希望直接响应通过SpringMVC渲染的页面,不需要经过Handler,可以使用mvc:view-controller标签实现

    <mvc:view-controller path="testJstlView" view-name="success"/>

    但是这样配置之后,原来的那些需要经过Handler的链接就将失效,实际上在实际开发中通常需要配置mvc:annotation-driven<mvc:annotation-driven/>,此时即可解决问题。

自定义视图

自定义视图需要实现View接口,并且需要在Spring的配置文件中配置BeanNameViewResolver,如下:

  • HelloView

    @Component
    public class HelloView implements View {@Overridepublic String getContentType() {return "text/html";}@Overridepublic void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {response.getWriter().print("hello view, time: " + new Date());}
    }

    HelloView实现View接口,需要实现两个接口,HelloView需要加上@Component注解从而注入到IOC容器中,这是因为BeanNameViewResolver需要从IOC容器中获取该View。

  • 配置文件的配置

    <!--配置视图解析器BeanNameViewResolver,使用视图的名字来解析视图-->
    <!--通过order属性来定义视图解析器的优先级,order值越小,优先级越高-->
    <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"><property name="order" value="100"/>
    </bean>
  • 测试

    @RequestMapping("/testView")
    public String testView() {System.out.println("testView");return "helloView";
    }

    需要注意的是testView()的返回值必须返回"helloView",这是因为HelloView在IOC容器的ID为helloView,而BeanNameViewResolver正是通过testView()方法的返回值在IOC容器中查找自定义View的。

关于重定向

  • 一般情况下控制器方法的返回字符串类型的值会被当成逻辑视图名处理
  • 如果返回的字符串中带forward:redirect:前缀时,SpringMVC会对他们进行特殊处理,将forward:和redirect:当成指示符,其后的字符串作为URL来处理。
    • redirect:success.jsp:会完成一个到success.jsp的重定向的操作
    • forward:success.jsp:会完成一个到success.jsp的转发操作

数据绑定

  • SpringMVC主框架将ServletRequest对象即目标方法的入参实例传递给WebDataBinderFactory实例,以创建DataBinder实例对象

  • DataBinder调用装配在SpringMVC上下文的ConversionService组件进行数据类型转换、数据格式化工作,将Servlet中的请求信息填充到入参对象中

  • 调用Validator组件对已经绑定了请求消息的入参对象进行数据合法性校验,并最终生成数据绑定结果BingingData对象

  • SpringMVC抽取BindingResult中的入参对象和校验错误对象,将它们赋给处理方法的响应入参

  • SpringMVC通过反射机制对目标处理方法进行解析,将请求消息绑定到处理方法的入参中,数据绑定的核心是DataBinder,运行机制如下:

自定义类型转换器

ConversionService是Spring类型转换体系的核心接口,可以利用ConversionServiceFactoryBean在Spring的IOC容器中定义一个ConversionService,Spring将自动识别出IOC容器中的ConversionService,并在Bean属性配置及SpringMVC处理方法入参绑定等场合使用它进行数据的转换。

可通过ConversionServiceFactoryBean的converters属性注册自定义的类型转换器。

Spring定义了3种类型的转换器接口,实现任意一个转换器接口都可以作为自定义转换器注册到ConversionServiceFactoryBean中:

  • Converter<S,T>:将S类型对象转为T类型对象
  • ConverterFactory:将相同系列多个同质的Converter封装在一起,如果希望将一种类型的对象转换为另一种类型及其子类型的对象(例如将String转换为Number及Number子类)可使用转换器工厂类
  • GenericConverter:会根据源类对象及目标类对象所在的宿主类中的上下文信息进行类型转换

<mvc:annotation-driven conversion-service="conversionService"/>会将自定义的ConversionService注册到SpringMVC的上下文中,例如:

<mvc:annotation-driven converson-service="conversionService"/>
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"><property name="converters"><list><bean class=""com.glemontree.springmvc.converters.UserConverter></bean></list></property>
</bean>

annotation-driven配置

有下面几种情况需要使用annotation-driven

  • 使用<mvc:view-controller/>配置直接转发的页面,无需经过Handler方法
  • 使用<mvc:default-servlet-handler/>配置访问静态资源文件
  • 在使用自定义类型转换器时使用<mvc:annotation-driven/>conversion-service属性

在开发过程中通常需要加入该配置。

<mvc:annotation-driven/>会自动注册RequestMappingHandlerMapping、RequestMappingHandlerAdapter以及ExceptionHandlerExceptionResoler三个bean,还提供以下支持:

  • 支持使用ConversionService实例对表单参数进行类型转换
  • 支持使用@NumberFormatannotaion、@DateTimeFormat注解完成数据类型的格式化
  • 支持使用@Valid注解对JavaBean实例进行JSR 303验证
  • 支持使用@ResponseBody@RequestBody注解

@InitBinder

  • @InitBinder标识的方法,可以对WebDataBinder对象进行初始化,WebDataBinder是DataBinder的子类,用于完成由表单字段到JavaBean属性的绑定。
  • @InitBinder方法不能有返回值,它必须声明为void
  • @InitBinder方法的参数值通常是WebDataBinder

例如:

// 不能自动绑定对象中的roleSet属性,另行处理
@InitBinder
public void initBinder(WebDataBinder dataBinder) {dataBinder.setDisallowedFields("roleSet");
}

数据的格式化

现在有这样一种情况,在Bean中有一个Date类型的对象,此时在表单中提交数据时会报错,因为SpringMVC无法知道你需要将什么样的数据转换为Date类型,此时需要在Bean的目标属性上面通过@DateTimeFormat注解声明日期的格式,例如:

@DateTimeFormat(pattern="yyyy-MM-dd")
private Date birth;

这个的前提是需要在SpringMVC的配置文件中配置:

<mvc:annotation-driven/>

另外一种情况,假设Bean中有一个float类型的属性:

private float salary;

现在在表单中输入1,234,567.8,此时也会出错,所以此时也需要在目标属性上加注解:

// 用#表示数值
@NumberFormat(pattern="#,###,###.#")
private float salary;

Spring在格式化模块中定义了一个实现ConversionService接口的FormattingConversionService实现类,该实现类扩展了GenericConversionService,因此它既具有类型转换的功能,又具有格式化的功能。

FormattingConversionService拥有一个FormattingConversionServiceFactoryBean工厂类,后者用于在Spring上下文中构造前者。

FormattingConversionServiceFactoryBean内部已经注册了:

  • NumberFormatAnnotationFormatterFactory:支持对数字类型的属性使用@NumberFormat注解
  • JodaDateTimeFormatAnnotationFormatterFactory:支持对日期类型的属性@DateTimeFormat注解

装配了FormattingConversionServiceFactoryBean后,就可以在Spring MVC入参绑定及模型数据输出时使用注解驱动了。

<mvc:annotation-driven/>默认创建的ConversionService实例即为FormattingConversionServiceFactoryBean。

数据校验

  • JSR 303是Java为Bean数据合法性校验提供的标准框架,它已经包含在JavaEE6.0中
  • JSR 303通过在Bean属性上标注类似于@NotNull@Max等标准的注解指定校验规则,并通过标准的验证接口对Bean进行验证。
  • Hibernate Validator是JSR 303的一个参考实现,除支持所有标准的校验注解外,它还支持以下的扩展注解:
    • @Email 被注解的元素必须是电子邮件地址
    • @Length 被注解的字符串的大小必须在指定的范围内
    • @NotEmpty 被注解的字符串必须非空
    • @Range 被注解的元素必须在合适的范围内
  • Spring4.0拥有自己的数据校验框架,同时支持JSR 303标准的校验框架
  • Spring在进行数据绑定时,可同时调用校验框架完成数据校验工作,在SpringMVC中,可直接通过注解驱动的方式进行数据校验
  • Spring的LocalValidatorFactoryBean既实现了Spring的Validator接口,也实现了JSR 303的Validator接口,只要在Spring容器里定义一个LocalValidatorFactoryBean,即可将其注入到需要数据校验的Bean中
  • Spring本身并没有提供JSR 303的实现,所以需要将JSR 303的实现者的JAR包放在类路径下。
  • <mvc:annotation-driven>会默认装配一个LocalValidatorFactoryBean,通过在处理方法的入参上标注@valid注解即可让SpringMVC在完成数据绑定后进行数据的校验
  • SpringMVC是通过对处理方法签名的规则来保存校验结果的:前一个表单/命令对象的校验结果保存在随后的入参中,这个保存校验结果的入参必须是BindingResult或Errors类型。
  • 整个校验的流程如下:
    • 使用JSR 303验证标准
    • 加入hibernate validator验证框架的Jar包
    • 在SpringMVC配置文件中加入<mvc:annotation-driven/>
    • 需要在bean的属性上添加对应的注解
    • 在目标方法bean类型的前面添加@Valid注解

错误消息

  • 显示错误消息

    在jsp中通过<form:errors/>标签进行错误消息的显示,该标签有一个属性path,若设置为*,则显示所有的错误消息。

    当然我们可以将错误消息分别显示在对应字段的后面,此时在对应字段的后面加上<form:errors/>标签,其path属性写上对应字段的名字就可以了,例如:

    LastName: <form:input path="lastName"/>
    <form-errors path="lastName"></form-errors>
  • 定制错误消息

    每个属性在数据绑定和数据校验发生错误时都会生成一个对应的FieldError对象。

    当一个属性校验失败后,校验框架会为该属性生成4和消息代码,这些代码以校验注解类名为前缀,结合modelAttribute、属性名和属性类型名生成多个对应的消息代码,例如User类中的password属性标注了一个@Pattern注解,当该属性不满足@Pattern所定义的规则时,就会产生下面4个消息代码:

    • Pattern.user.password
    • Pattern.password
    • Pattern.java.lang.String
    • Pattern

    当使用SpringMVC标签显示错误消息时,SpringMVC会查看WEB上下文是否装配了对应的国际化消息,如果没有,则显示默认的错误消息,否则使用国际化消息。

这篇关于[SpringMVC] SpringMVC的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/972472

相关文章

java设计模式之工厂模式--普通工厂方法模式(Factory Method)

1.普通工厂模式,就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。 2.先定义一个接口: package com.zhong.pattern.factorymethod;/*** 发送接口* @author admin**/public interface Sender {/*** 发送消息方法* @param msg*/void send(String msg);} 3

Java设计模式之代理模式2-动态代理(jdk实现)

这篇是接着上一篇继续介绍java设计模式之代理模式。下面讲解的是jdk实现动态代理。 1.)首先我们要声明一个动态代理类,实现InvocationHandler接口 package com.zhong.pattern.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;/*** 演

java设计模式之代理模式1--静态代理

Java编程的目标是实现现实不能完成的,优化现实能够完成的,是一种虚拟技术。生活中的方方面面都可以虚拟到代码中。代理模式所讲的就是现实生活中的这么一个概念:助手。 代理模式的定义:给某一个对象提供一个代理,并由代理对象控制对原对象的引用。 1.)首先新建一个表演的接口 package com.zhong.pattern.proxy;/*** 表演接口* @author admin*

java原型(Prototype)设计模式

原型模式就是讲一个对象作为原型,使用clone()方法来创建新的实例。 public class Prototype implements Cloneable{private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}@Overri

Java中23种设计模式之适配者模式

适配器模式的作用就是在原来的类上提供新功能。 主要可分为3种: 1.类适配:创建新类,继承源类,并实现新接口,例如:     class Adapter extends OldClass implements NewFunc{} 2.对象适配:创建新类持源类的实例,并实现新接口,例如:     class Adapter implements NewFunc { priva

java不依赖临时变量交换两个变量的值

java不依赖临时变量交换两个变量的值 1.简单易懂的实现方式     int a=1,b=2;     int temp = 0;     temp = a;     a = b;     b= temp; 2.算术算法 int a=1,b=2; a = a+b;// a = 1+2  b = a-b;// b = a-b --> b=3-2 -->1 a = a -b;/

Java中的SOLID原则及示例

类是任何Java应用程序的构建块。如果这些区块不强,那么建筑(即应用)将来将面临艰难时期。这实际上意味着,当应用程序范围上升或应用程序在生产或维护中面临某些设计问题时,不那么好的编写会导致非常困难的情况。 另一方面,一组精心设计和编写的类可以加速编码过程的突飞猛进,同时减少错误的数量。 在本教程中,我们将使用 5个最推荐的设计原则的示例来讨论Java中的SOLID原则,在编写类时我们应该记住这

Java比较和交换示例 - CAS算法

Java比较和交换示例 - CAS算法 由Lokesh Gupta | 提起下:多线程 一个Java 5中最好添加的是支持类,如原子操作AtomicInteger,AtomicLong等等。这些课程帮助您最大限度地减少复杂的(非必要)需要多线程的,如增加一些基本的操作代码或递减的值在多个线程之间共享。这些类内部依赖于名为CAS(比较和交换)的算法。在本文中,我将详细讨论这个概念。 1.乐观和

java并发编程之CyclicBarrier(循环栅栏)

package com.zhong;import java.util.concurrent.CyclicBarrier;/*** Cyclic意思是循环,Barrier意思是屏障,那么CyclicBarrier翻译过来就是循环栅栏。* 它是一个同步辅助类,能让一组线程互相等待,* 直到这一组线程都到了一个公共屏障点,各线程才能继续向下执行。因为该屏障能够在释放等待线程后继续重用,所以叫循环屏障。*

Java内存管理 - 垃圾收集算法

我们都知道Java 中垃圾收集器 [GC] 的功能。但只有少数人试图深入了解垃圾收集的工作原理。你不是其中之一,这就是你在这里的原因。 在这个Java内存管理教程中,我们将尝试了解Java垃圾收集的当前算法,我们将了解这些算法的演变。 目录1. Java中的内存管理2.引用计数机制3.标记和清除机制4.停止并复制GC 5.分代停止和复制6.如何提高Java中的内存利用率 1.