代理设计模式示例

本文是我们名为“ Java设计模式 ”的学院课程的一部分。

在本课程中,您将深入研究大量的设计模式,并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因,并了解何时以及如何应用模式中的每一个。 在这里查看 !

目录

1.简介 2.什么是代理模式 3.远程代理 4.虚拟代理 5.保护代理 6.何时使用代理模式 7.其他代理 8. JDK中的代理模式 9.下载源代码

1.简介

在本课程中,我们将讨论结构模式,即代理模式。 代理模式为另一个对象提供代理或占位符,以控制对其的访问。

代理模式提供了许多不同的变体。 一些重要的变体是远程代理,虚拟代理和保护代理。 在本课程中,我们将对这些变体有更多的了解,并将使用Java来实现它们。 但是在我们这样做之前,让我们先全面了解代理模式。

2.什么是代理模式

代理模式用于创建代表对象,该对象控制对另一个对象的访问,该对象可能是远程的,创建起来很昂贵,或者需要保护。

控制对对象的访问的一个原因是将创建和初始化的全部成本推迟到我们实际需要使用它之前。 另一个原因可能是充当驻留在不同JVM中的对象的本地代表。 代理对于控制对原始对象的访问非常有用,尤其是当对象应具有不同的访问权限时。

在代理模式中,客户端不直接与原始对象对话,而是将其调用委托给代理对象,该代理对象调用原始对象的方法。 重要的一点是客户端不了解代理,代理充当客户端的原始对象。 但是这种方法有很多变化,我们将很快看到。

让我们看一下代理模式及其重要参与者的结构。

图1

图1

  1. 代理人
    1a。 维护一个使代理可以访问真实主题的参考。 如果RealSubject和Subject接口相同,则代理可以引用Subject。
    1b。 提供与Subject相同的接口,以便可以用代理代替真实的Subject。 1c。 控制对真实主题的访问,并可能负责创建和删除它。
  2. 主题
    2a。 为RealSubject和Proxy定义公共接口,以便可以在需要RealSubject的任何地方使用Proxy。
  3. RealSubject
    3a。 定义代理代表的真实对象。

代理模式有三个主要变体:

  1. 远程代理为不同地址空间中的对象提供了本地代表。
  2. 虚拟代理根据需要创建昂贵的对象。
  3. 保护代理控制对原始对象的访问。 当对象应具有不同的访问权限时,保护代理很有用。

我们将在下一部分中逐一讨论这些代理。

3.远程代理

有一家披萨公司,其在各个位置都有分店。 公司的所有者每天都会从各个网点获得公司员工的每日报告。 Pizza Company支持的当前应用程序是桌面应用程序,而不是Web应用程序。 因此,所有者必须要求其雇员生成报告并将其发送给他。 但是现在所有者希望自己生成并检查报告,以便他可以在任何人需要的情况下随时生成报告,而无需任何人的帮助。 所有者希望您为他开发一个应用程序。

这里的问题是所有应用程序都在各自的JVM上运行,而Report Checker应用程序(我们将很快设计)应在所有者的本地系统中运行。 所有者的系统JVM中不存在生成报告所需的对象,并且您不能直接调用远程对象。

远程代理用于解决此问题。 我们知道该报告是由用户生成的,因此需要一个对象来生成报告。 我们所需要做的就是联系位于远程位置的对象,以获得所需的结果。 远程代理充当远程对象的本地代表。 远程对象是驻留在不同JVM堆中的对象。 您将方法调用到本地对象,该方法将调用转移到远程对象。

您的客户端对象的行为类似于其进行远程方法调用。 但这是在处理本地所有网络通信底层细节的堆本地代理对象上调用方法。

Java支持使用RMI在位于两个不同位置(或两个不同JVM)的两个对象之间进行通信。 RMI是远程方法调用,用于构建客户端和服务帮助程序对象,直至使用与远程服务相同的方法创建客户端帮助程序对象。 使用RMI,您不必自己编写任何网络或I / O代码。 使用客户端,您可以像在客户端的本地JVM中运行的对象上的普通方法调用一样调用远程方法。

RMI还提供了运行中的基础结构以使其全部正常工作,包括客户端可以用来查找和访问远程对象的查找服务。 RMI调用和本地方法调用之间有一个区别。 客户助手通过网络发送方法调用,因此RMI调用涉及网络和I / O。

现在让我们看一下代码。 我们有一个接口ReportGenerator及其具体实现ReportGeneratorImpl已经在不同位置的JVM上运行。 首先要创建一个远程服务,我们需要更改代码。

ReportGenerator接口现在将如下所示:

package com.javacodegeeks.patterns.proxypattern.remoteproxy;import java.rmi.Remote;
import java.rmi.RemoteException;public interface ReportGenerator extends Remote{public String generateDailyReport() throws RemoteException;}

这是一个远程接口,它定义客户端可以远程调用的方法。 客户端将使用它作为您的服务的类类型。 Stub和实际服务都将实现此目的。 接口中的方法返回String对象。 您可以从该方法返回任何对象; 该对象将通过电线从服务器传送回客户端,因此它必须是Serializable 。 请注意,此接口中的所有方法都应抛出RemoteException

package com.javacodegeeks.patterns.proxypattern.remoteproxy;import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Date;public class ReportGeneratorImpl extends UnicastRemoteObject implements ReportGenerator{private static final long serialVersionUID = 3107413009881629428L;protected ReportGeneratorImpl() throws RemoteException {}@Overridepublic String generateDailyReport() throws RemoteException {StringBuilder sb = new StringBuilder();sb.append("********************Location X Daily Report********************");sb.append("\\n Location ID: 012");sb.append("\\n Today's Date: "+new Date());sb.append("\\n Total Pizza's Sell: 112");sb.append("\\n Total Price: $2534");sb.append("\\n Net Profit: $1985");sb.append("\\n ***************************************************************");return sb.toString();}public static void main(String[] args) {try {ReportGenerator reportGenerator = new ReportGeneratorImpl();Naming.rebind("PizzaCoRemoteGenerator", reportGenerator);} catch (Exception e) {e.printStackTrace();}}}

上面的类是完成实际工作的远程实现。 客户端希望在其上调用方法的对象。 该类扩展了UnicastRemoteObject ,为了用作远程服务对象,您的对象需要一些与远程相关的功能。 最简单的方法是从java.rmi.server包中扩展UnicastRemoteObject ,然后让该类为您完成工作。

UnicastRemoteObject类构造函数将引发RemoteException ,因此您需要编写一个声明了RemoteException的无参数构造函数。

为了使远程服务可用于客户端,您需要在RMI注册表中注册该服务。 您可以通过实例化并将其放入RMI注册表来完成此操作。 注册实现对象时,RMI系统实际上将存根放在注册表中,因为这是客户端需要的。 Naming.rebind方法用于注册对象。 它有两个参数,第一个用于命名服务的字符串,另一个参数带有将由客户端获取以使用服务的对象。

现在,要创建存根,您需要在远程实现类上运行rmic 。 Rmic工具随Java软件开发人员一起提供,实现服务实现并创建一个新的存根。 您应该打开命令提示符(cmd),并从远程实现所在的目录运行rmic。

下一步是运行rmiregistry,打开一个终端并启动注册表,只需键入命令rmir​​egistry 。 但是请确保从具有访问类权限的目录中启动它。

最后一步是启动服务,即运行远程类的具体实现,在这种情况下,该类为ReportGeneratorImpl

到目前为止,我们已经创建并运行了服务。 现在,让我们看看客户端将如何使用它。 比萨公司所有者的报表应用程序将使用此服务来生成和检查报表。 我们需要向将使用该服务的客户端提供ReportGenerator接口和存根。 您可以简单地交付存根以及服务中所需的任何其他类或接口。

package com.javacodegeeks.patterns.proxypattern.remoteproxy;import java.rmi.Naming;public class ReportGeneratorClient {public static void main(String[] args) {new ReportGeneratorClient().generateReport();}public void generateReport(){try {ReportGenerator reportGenerator = (ReportGenerator)Naming.lookup("rmi://127.0.0.1/PizzaCoRemoteGenerator");System.out.println(reportGenerator.generateDailyReport());} catch (Exception e) {e.printStackTrace();}}}

上面的程序将具有以下输出:

********************Location X Daily Report********************Location ID: 012Today's Date: Sun Sep 14 00:11:23 IST 2014Total Pizza Sell: 112Total Sale: $2534Net Profit: $1985***************************************************************

上面的类进行命名查找,并检索用于生成每日报告的对象。 您需要提供主机名的IP和用于绑定服务的名称。 其余的看起来就像是一个常规的旧方法调用。

总之,远程代理充当驻留在不同JVM中的对象的本地代表。 代理上的方法调用导致该调用通过有线传输,远程调用,并将结果返回给代理,然后返回给客户端。

4.虚拟代理

虚拟代理模式是一种节省内存的技术,建议将对象创建推迟到需要时再进行。 它在创建对象时使用,在内存使用或所涉及的处理方面非常昂贵。 在典型的应用程序中,不同的对象组成功能的不同部分。 启动应用程序时,它可能不需要其所有对象立即可用。 在这种情况下,虚拟代理模式建议将对象创建推迟到应用程序需要时再进行。 第一次创建的对象在应用程序中被引用,并且从该点开始重复使用同一实例。 这种方法的优点是应用程序启动时间更快,因为不需要创建和加载所有应用程序对象。

假设您的应用程序中有一个Company对象,并且此对象在ContactList对象中包含该公司的雇员列表。 公司中可能有数千名员工。 从数据库中加载Company对象以及ContactList对象中所有雇员的列表可能非常耗时。 在某些情况下,您甚至不需要雇员列表,但是您不得不等到公司及其雇员列表加载到内存中。

节省时间和内存的一种方法是避免在需要之前加载员工对象,而这是使用虚拟代理完成的。 该技术也称为延迟加载,您仅在需要时才获取数据。

package com.javacodegeeks.patterns.proxypattern.virtualproxy;public class Company {private String companyName;private String companyAddress;private String companyContactNo;private ContactList contactList ;public Company(String companyName,String companyAddress, String companyContactNo,ContactList contactList){this.companyName = companyName;this.companyAddress = companyAddress;this.companyContactNo = companyContactNo;this.contactList = contactList;System.out.println("Company object created...");}public String getCompanyName() {return companyName;}public String getCompanyAddress() {return companyAddress;}public String getCompanyContactNo() {return companyContactNo;}public ContactList getContactList(){return contactList;}}

上面的Company类具有对ContactList接口的引用,该接口的真实对象仅在请求调用getContactList()方法时才加载。

package com.javacodegeeks.patterns.proxypattern.virtualproxy;import java.util.List;public interface ContactList {public List<Employee> getEmployeeList();
}

ContactList接口仅包含一种方法getEmployeeList() ,该方法用于获取公司的员工列表。

package com.javacodegeeks.patterns.proxypattern.virtualproxy;import java.util.ArrayList;
import java.util.List;public class ContactListImpl implements ContactList{@Overridepublic List<Employee> getEmployeeList() {return getEmpList();}private static List<Employee>getEmpList(){List<Employee> empList = new ArrayList<Employee>(5);empList.add(new Employee("Employee A", 2565.55, "SE"));empList.add(new Employee("Employee B", 22574, "Manager"));empList.add(new Employee("Employee C", 3256.77, "SSE"));empList.add(new Employee("Employee D", 4875.54, "SSE"));empList.add(new Employee("Employee E", 2847.01, "SE"));return empList;}}

上面的类将创建一个实际的ContactList对象,该对象将返回公司的员工列表。 仅在需要时才按需加载对象。

package com.javacodegeeks.patterns.proxypattern.virtualproxy;import java.util.List;public class ContactListProxyImpl implements ContactList{private ContactList contactList;@Overridepublic List<Employee> getEmployeeList() {if(contactList == null){System.out.println("Creating contact list and fetching list of employees...");contactList = new ContactListImpl();}return contactList.getEmployeeList();}}

ContactListProxyImpl是代理类,它也实现ContactList并保存对实际ContactList对象的引用。 在方法getEmployeeList()的实现上,它将检查contactList引用是否为null,然后将创建一个实际的ContactList对象,然后将对其调用getEmployeeList()方法以获取员工列表。

Employee类看起来像这样。

package com.javacodegeeks.patterns.proxypattern.virtualproxy;public class Employee {private String employeeName;private double employeeSalary;private String employeeDesignation;public Employee(String employeeName,double employeeSalary,String employeeDesignation){this.employeeName = employeeName;this.employeeSalary = employeeSalary;this.employeeDesignation = employeeDesignation;}public String getEmployeeName() {return employeeName;}public double getEmployeeSalary() {return employeeSalary;}public String getEmployeeDesignation() {return employeeDesignation;}public String toString(){return "Employee Name: "+employeeName+", EmployeeDesignation: "+employeeDesignation+", Employee Salary: "+employeeSalary;}}package com.javacodegeeks.patterns.proxypattern.virtualproxy;import java.util.List;public class TestVirtualProxy {public static void main(String[] args) {ContactList contactList = new ContactListProxyImpl();Company company = new Company("ABC Company", "India", "+91-011-28458965", contactList);System.out.println("Company Name: "+company.getCompanyName());System.out.println("Company Address: "+company.getCompanyAddress());System.out.println("Company Contact No.: "+company.getCompanyContactNo());System.out.println("Requesting for contact list");contactList = company.getContactList();List<Employee>empList = contactList.getEmployeeList();for(Employee emp : empList){System.out.println(emp);}}}

上面的程序将具有以下输出:

Company object created...
Company Name: ABC Company
Company Address: India
Company Contact No.: +91-011-28458965
Requesting for contact list
Creating contact list and fetching list of employees...
Employee Name: Employee A, EmployeeDesignation: SE, Employee Salary: 2565.55
Employee Name: Employee B, EmployeeDesignation: Manager, Employee Salary: 22574.0
Employee Name: Employee C, EmployeeDesignation: SSE, Employee Salary: 3256.77
Employee Name: Employee D, EmployeeDesignation: SSE, Employee Salary: 4875.54
Employee Name: Employee E, EmployeeDesignation: SE, Employee Salary: 2847.01

如您在TestVirtualProxy生成的输出中所TestVirtualProxy ,首先我们创建了一个带有代理ContactList对象的Company对象。 此时, Company对象保存一个代理引用,而不是真实的ContactList对象的引用,因此内存中没有加载任何员工列表。 我们对公司对象进行了一些调用,然后使用getEmployeeList()方法从联系人列表代理对象中请求雇员列表。 调用此方法时,代理对象将创建一个实际的ContactList对象并提供雇员列表。

5.保护代理

通常,应用程序中的对象相互交互以实现整体应用程序功能。 通常,大多数应用程序对象可由应用程序中的所有其他对象访问。 有时,可能有必要根据对象的访问权限将对象的可访问性仅限制为一组有限的客户端对象。 当客户端对象尝试访问此类对象时,仅当客户端可以提供适当的身份验证凭据时,才可以向客户端授予对该对象提供的服务的访问权限。 在这种情况下,可以指定一个单独的对象,负责验证不同客户端对象在访问实际对象时的访问权限。 换句话说,每个客户端都必须成功与此指定对象进行身份验证才能访问实际的对象功能。 客户端需要通过身份验证才能访问实际对象的此类对象可以称为使用保护代理实现的对象身份验证器。

返回到我们为披萨公司开发的ReportGenerator应用程序,所有者现在要求只有他才能生成每日报告。 没有其他员工应该能够这样做。

为了实现此安全功能,我们使用了保护代理,该代理可以检查试图生成报告的对象是否为所有者; 在这种情况下,将生成报告,否则不会生成。

package com.javacodegeeks.patterns.proxypattern.protectionproxy;public interface Staff {public boolean isOwner();public void setReportGenerator(ReportGeneratorProxy reportGenerator);
}

Staff接口由OwnerEmployeeOwner ,并且该接口具有两种方法: isOwner()返回一个boolean以检查调用对象是否为所有者。 另一个方法用于设置ReportGeneratorProxy ,它是用于生成报告的保护代理, isOwner()方法返回true。

package com.javacodegeeks.patterns.proxypattern.protectionproxy;public class Employee implements Staff{private ReportGeneratorProxy reportGenerator;@Overridepublic void setReportGenerator(ReportGeneratorProxy reportGenerator){this.reportGenerator = reportGenerator;}@Overridepublic boolean isOwner() {return false;}public String generateDailyReport(){try {return reportGenerator.generateDailyReport();} catch (Exception e) {e.printStackTrace();}return "";}}

Employee类实现了Staff接口,因为它是一个雇员isOwner()方法,返回falsegenerateDailyReport()方法要求ReportGenerator生成每日报告。

package com.javacodegeeks.patterns.proxypattern.protectionproxy;public class Owner implements Staff {private boolean isOwner=true;private ReportGeneratorProxy reportGenerator;@Overridepublic void setReportGenerator(ReportGeneratorProxy reportGenerator){this.reportGenerator = reportGenerator;}@Overridepublic boolean isOwner(){return isOwner;}public String generateDailyReport(){try {return reportGenerator.generateDailyReport();} catch (Exception e) {e.printStackTrace();}return "";}}

Owner类看起来与Employee类几乎相同,唯一的区别是isOwner()方法返回true

package com.javacodegeeks.patterns.proxypattern.protectionproxy;public interface ReportGeneratorProxy {public String generateDailyReport();
}

ReportGeneratorProxy充当保护代理,它只有一种用于生成报告的方法generateDailyReport()

package com.javacodegeeks.patterns.proxypattern.protectionproxy;import java.rmi.Naming;import com.javacodegeeks.patterns.proxypattern.remoteproxy.ReportGenerator;public class ReportGeneratorProtectionProxy implements ReportGeneratorProxy{ReportGenerator reportGenerator;Staff staff;public ReportGeneratorProtectionProxy(Staff staff){this.staff = staff;}@Overridepublic String generateDailyReport() {if(staff.isOwner()){ReportGenerator reportGenerator = null;try {reportGenerator = (ReportGenerator)Naming.lookup("rmi://127.0.0.1/PizzaCoRemoteGenerator");return reportGenerator.generateDailyReport();} catch (Exception e) {e.printStackTrace();}return "";}else{return "Not Authorized to view report.";}}
}

上面的类是ReportGeneratorProxy的具体实现,其中包含对作为远程代理的ReportGenerator接口的引用。 在generateDailyReport()方法中,它检查工作人员是否正在引用所有者,然后要求远程代理生成报告,否则它返回带有“未授权查看报告”的字符串作为消息。

package com.javacodegeeks.patterns.proxypattern.protectionproxy;public class TestProtectionProxy {public static void main(String[] args) {Owner owner = new Owner();ReportGeneratorProxy reportGenerator = new ReportGeneratorProtectionProxy(owner);owner.setReportGenerator(reportGenerator);Employee employee = new Employee();reportGenerator = new ReportGeneratorProtectionProxy(employee);employee.setReportGenerator(reportGenerator);System.out.println("For owner:");System.out.println(owner.generateDailyReport());System.out.println("For employee:");System.out.println(employee.generateDailyReport());}}

上面的程序将具有以下输出:

For owner:
********************Location X Daily Report********************Location ID: 012Today's Date: Sun Sep 14 13:28:12 IST 2014Total Pizza Sell: 112Total Sale: $2534Net Profit: $1985***************************************************************
For employee:
Not Authorized to view report.

以上输出清楚地表明,所有者可以生成报告,而员工则不能。 保护代理保护访问生成报告的权限,并且仅允许授权对象生成报告。

6.何时使用代理模式

只要需要对对象的引用比简单的指针更广泛或更复杂,就可以使用代理。 这是代理模式适用的几种常见情况:

  1. 远程代理为不同地址空间中的对象提供了本地代表。
  2. 虚拟代理根据需要创建昂贵的对象。
  3. 保护代理控制对原始对象的访问。 当对象应具有不同的访问权限时,保护代理很有用。

7.其他代理

除了上面讨论的三个主要代理外,还有其他一些代理。

  1. 缓存代理/服务器代理 :提供存储最常用目标操作的结果所需的功能。 代理对象将这些结果存储在某种存储库中。 当客户端对象请求相同的操作时,代理将从存储区域返回操作结果,而无需实际访问目标对象。
  2. 防火墙代理防火墙代理的主要用途是保护目标对象免受不良客户端的攻击。 防火墙代理还可用于提供防止客户端访问有害目标所需的功能。
  3. 同步代理 :提供所需的功能,以允许不同的客户端对象安全并发地访问目标对象。
  4. 智能参考代理 :提供功能,以防止当前有客户端对其进行引用时意外处置/删除目标对象。 为此,代理会保留对目标对象的引用数量的计数。 如果并且在没有引用时,代理会删除目标对象。
  5. 计数代理 :在对目标对象执行方法之前,提供某种审核机制。

8. JDK中的代理模式

以下情况是在JDK中使用代理模式的示例。

  1. java.lang.reflect.Proxy
  2. java.rmi.* (whole package)

9.下载源代码

这是关于代理模式的课程。 您可以在此处下载源代码: ProxyPattern-Project.zip

翻译自: https://www.javacodegeeks.com/2015/09/proxy-design-pattern.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/356804.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

调研《构建之法》指导下的历届作品

项目名称&#xff1a;未视APP学校&#xff1a;吉首大学团队&#xff1a;北京必趣科技有限公司 简介&#xff1a;发现未知的视界http://plus.jlu.edu.cn/item.php?id377 延续电影瞬间的感动&#xff0c;发现视界未知的温暖 理由:无优势,很多劣势,可是延续电影瞬间的感动&#x…

java图形旋转动画_Java动画:旋转图像

我将假设您了解如何旋转图像一次.如果你不这样做,你可以通过快速谷歌搜索找到它.您需要的是一个为您旋转它的后台进程.它的工作原理如下&#xff1a;/*** Warning - this class is UNSYNCHRONIZED!*/public class RotatableImage {Image image;float currentDegrees;public Rot…

java golang速度_golang思考之运行速度

有些资料显示golang的运行速度很慢&#xff0c;比Java慢&#xff0c;有时比Python慢。学习吧测试发现golang的运行速度和Java差不多。首先&#xff0c;使用各种语言编写同一个CPU密集的程序sum。C(或C)#include #include #include int main(void){int iN;int64_t jN;scanf(&quo…

java 中的正则表达式_Java中的正则表达式–软介绍

java 中的正则表达式正则表达式是一种可以应用于文本&#xff08;Java中的String&#xff09;的模式。 Java提供了java.util.regex包&#xff0c;用于与正则表达式进行模式匹配。 Java正则表达式与Perl编程语言非常相似&#xff0c;并且非常易于学习。 正则表达式匹配文本&…

HTML5移动端触摸事件

工作了近一个月了 因为公司是主要偏向于移动端&#xff0c;开始不懂移动端事件 一直用的click click在安卓端没有什么问题 但在IOS端就有问题了点击之后会延迟半秒 多亏旁边大神指点 原来 iOS上的Safari也支持click 和mouseover等传统的交互事件&#xff0c;只是不推荐在iOS…

用java写的教职工信息管理系统_基于Java的教师信息管理系统的设计与实现论文.doc...

基于Java的教师信息管理系统的设计与实现论文职场大变样社区()&#xff1a;下载毕业设计成品全套资料&#xff0c;全部50元以下毕业设计(论文)任务书第1页毕业设计(论文)题目&#xff1a;基于java的教师信息管理系统的设计与实现毕业设计(论文)要求及原始数据(资料)&#xff1a…

春云边车

我有一个部署到基于NetflixOSS的云的应用程序&#xff0c;该应用程序具有以下结构&#xff1a; 本质上是一种将信息持久保存到Cassandra群集的服务。 所有应用程序都已注册到Eureka –因此&#xff0c;在本例中&#xff0c;该服务以及Cassandra节点都已在Eureka中注册&#xf…

java json写入内存_如何在客户端上减少JSON.stringify使用的内存量?

使用JSON.stringify将大型javascript对象转换为字符串时&#xff0c;有没有办法减少客户端上的内存使用量&#xff1f;我正在寻找解决下面问题的东西&#xff0c;但是对于客户端上的javascript .当我尝试一个简单的JSON.stringify(big_object)时&#xff0c;它会迅速占用所有RA…

GridView的一些常用属性:

GridView的一些常用属性&#xff1a;android:numColumns”auto_fit” //GridView的列数设置为自动android:columnWidth”90dp " //每列的宽度&#xff0c;也就是Item的宽度android:stretchMode”columnWidth" //缩放与列宽大小同步android:verticalSpacing…

activemq端口好_ActiveMQ已准备好黄金时段

activemq端口好ActiveMQ项目始于2005年-在很大程度上&#xff0c;它一直是Apache Software Foundation的顶级项目。 ActiveMQ项目的目的一直是提供世界一流的企业消息传递解决方案&#xff0c;使经纪人能够提供从支持IP的智能设备一直到企业后端的高可用性的连通性。 ActiveMQ提…

js创建节点,小试牛刀

实现如下的功能 非常简单的一个小训练。 思想&#xff1a; 1.首先创建text和一个button 代码如下、 1 <body> 2 <input type"text" id"text1"/> 3 <input id"btn1" type"button" value"创建" /> 4 <u…

java 8是指什么_java中8个基本数据类型到底是指什么?是什么意思,有什么作用?我需要权威的回答,...

在java中一共有八种基本数据类型&#xff0c;他们分别是byte、short、int、long、float、double、char、boolean整型其中byte、short、int、long都是表示整数的&#xff0c;只不过他们的取值范围不一样byte的取值范围为-128~127&#xff0c;占用1个字节(-2的7次方到2的7次方-1)…

企业讯息

本文是我们名为“ Spring Integration for EAI ”的学院课程的一部分。 在本课程中&#xff0c;向您介绍了企业应用程序集成模式以及Spring Integration如何解决它们。 接下来&#xff0c;您将深入研究Spring Integration的基础知识&#xff0c;例如通道&#xff0c;转换器和适…

php生成txt文件_php 批量生成html,txt文件的实现代码

本篇文章是对使用php批量生成html,txt文件的实现代码进行了详细的分析介绍&#xff0c;需要的朋友参考下首先建立一个conn.php的文件用来链接数据库$link mysql_connect("mysql_host" , "mysql_user" , "mysql_password" )or die("Could n…

HDU 3665 Seaside

题目链接&#xff1a; http://acm.split.hdu.edu.cn/showproblem.php?pid3665 Problem DescriptionXiaoY is living in a big city, there are N towns in it and some towns near the sea. All these towns are numbered from 0 to N-1 and XiaoY lives in the town numbered…

Spring MVC 学习笔记一 HelloWorld

Spring MVC 学习笔记一 HelloWorld Spring MVC 的使用可以按照以下步骤进行&#xff08;使用Eclipse&#xff09;&#xff1a; 加入JAR包在web.xml中配置DispatcherServlet加入Spring MVC的配置文件编写处理请求的处理器&#xff0c;并添加对应注解编写视图下面按照国际惯例先来…

php 避免xss_PHP防止XSS注入

我们在做网站的时候&#xff0c;经常有input提交&#xff0c;通常前端对input中的内容不做判断&#xff0c;只做不为空等简单的操作。但是&#xff0c;有的input中会提交一些javascript或者html,会给网站造成一定的危害。为此&#xff0c;防止XSS注入的任务交给了后端&#xff…

为什么选择Docker?

容器并不是什么新鲜事物&#xff0c;但是实现它们总是比需要的要复杂一些。 Docker在简化容器方面取得了长足的进步&#xff0c;并从此引爆了整个世界。 让我们看看为什么。 为什么Docker成为家喻户晓的名字 Docker不是很老。 2014年5月&#xff0c;当我写了一篇煽动性博客文章…

全字符微信名 php,PHP方法处理微信昵称特殊符号过滤

我们在通过PHP获取微信昵称&#xff0c;并且存于数据库的时候&#xff0c;由于一些昵称带有特殊符号&#xff0c;所以存不进去&#xff0c;这时候我们可以通过下面的方式来处理。方法二protected function removeEmoji($clean_text) {// Match Emoticons$regexEmoticons /[\x{…

[转载]我的PMP复习备考经验谈(下篇)——一本关于PMP备考的小指南

原文地址&#xff1a;我的PMP复习备考经验谈(下篇)——一本关于PMP备考的小指南作者&#xff1a;羽少宸PMP复习备考经验谈&#xff08;下篇&#xff09;——PMP备考小指南 总结经验&#xff0c;展望未来&#xff0c;以此纪念PMP复习备考时光 继上篇&#xff0c;猛击直达四、如何…