diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e02cf48
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+/.project
+/.settings
+/src
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..ea644d2
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,15 @@
+
+ 4.0.0
+ net.aimeizi
+ maven-framework-project
+ 1.0.0
+ pom
+
+ spring3-javaconfig-example
+ spring3-helloworld-example
+ spring3-javaconfig-import-example
+ spring3-mvc-simple
+ spring3-jmx-example
+ spring3-rmi-example
+
+
\ No newline at end of file
diff --git a/spring3-helloworld-example/.gitignore b/spring3-helloworld-example/.gitignore
new file mode 100644
index 0000000..9dff9cc
--- /dev/null
+++ b/spring3-helloworld-example/.gitignore
@@ -0,0 +1,4 @@
+/.project
+/.settings
+/target
+/.classpath
diff --git a/spring3-helloworld-example/pom.xml b/spring3-helloworld-example/pom.xml
new file mode 100644
index 0000000..7bee7ae
--- /dev/null
+++ b/spring3-helloworld-example/pom.xml
@@ -0,0 +1,28 @@
+
+ 4.0.0
+
+ net.aimeizi
+ maven-framework-project
+ 1.0.0
+
+ spring3-helloworld-example
+
+
+
+ org.springframework
+ spring-core
+ ${spring.version}
+
+
+ org.springframework
+ spring-context
+ ${spring.version}
+
+
+
+
+ 3.2.3.RELEASE
+
+
+
\ No newline at end of file
diff --git a/spring3-helloworld-example/src/main/java/net/aimeizi/helloworld/example/App.java b/spring3-helloworld-example/src/main/java/net/aimeizi/helloworld/example/App.java
new file mode 100644
index 0000000..18f237e
--- /dev/null
+++ b/spring3-helloworld-example/src/main/java/net/aimeizi/helloworld/example/App.java
@@ -0,0 +1,26 @@
+package net.aimeizi.helloworld.example;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class App {
+
+ @SuppressWarnings("resource")
+ public static void main(String[] args) {
+
+ /**
+ * Create a new ApplicationContext, loading the
+ * definitions from the given XML file
+ */
+ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
+ /**
+ * Return an instance, which may be shared or
+ * independent, of the specified bean.
+ */
+ HelloWorldService obj = (HelloWorldService) context.getBean("helloWorldService");
+ obj.setName("Spring 3.2.3");
+ String message =obj.sayHello();
+ System.out.println(message);
+ }
+
+}
diff --git a/spring3-helloworld-example/src/main/java/net/aimeizi/helloworld/example/HelloWorldService.java b/spring3-helloworld-example/src/main/java/net/aimeizi/helloworld/example/HelloWorldService.java
new file mode 100644
index 0000000..8387d5b
--- /dev/null
+++ b/spring3-helloworld-example/src/main/java/net/aimeizi/helloworld/example/HelloWorldService.java
@@ -0,0 +1,18 @@
+package net.aimeizi.helloworld.example;
+
+import org.springframework.stereotype.Service;
+
+@Service("helloWorldService")
+public class HelloWorldService {
+
+ private String name;
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String sayHello() {
+ return "Hello from HelloWorld Service! " + name;
+ }
+
+}
diff --git a/spring3-helloworld-example/src/main/resources/applicationContext.xml b/spring3-helloworld-example/src/main/resources/applicationContext.xml
new file mode 100644
index 0000000..a13878d
--- /dev/null
+++ b/spring3-helloworld-example/src/main/resources/applicationContext.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring3-javaconfig-example/.gitignore b/spring3-javaconfig-example/.gitignore
new file mode 100644
index 0000000..9dff9cc
--- /dev/null
+++ b/spring3-javaconfig-example/.gitignore
@@ -0,0 +1,4 @@
+/.project
+/.settings
+/target
+/.classpath
diff --git a/spring3-javaconfig-example/pom.xml b/spring3-javaconfig-example/pom.xml
new file mode 100644
index 0000000..498c35b
--- /dev/null
+++ b/spring3-javaconfig-example/pom.xml
@@ -0,0 +1,34 @@
+
+ 4.0.0
+
+ net.aimeizi
+ maven-framework-project
+ 1.0.0
+
+ spring3-javaconfig-example
+
+
+
+
+ org.springframework
+ spring-core
+ ${spring.version}
+
+
+ org.springframework
+ spring-context
+ ${spring.version}
+
+
+ cglib
+ cglib
+ 3.0
+
+
+
+
+ 3.2.3.RELEASE
+
+
+
\ No newline at end of file
diff --git a/spring3-javaconfig-example/src/main/java/net/aimeizi/javaconfig/example/App.java b/spring3-javaconfig-example/src/main/java/net/aimeizi/javaconfig/example/App.java
new file mode 100644
index 0000000..31b1a8f
--- /dev/null
+++ b/spring3-javaconfig-example/src/main/java/net/aimeizi/javaconfig/example/App.java
@@ -0,0 +1,26 @@
+package net.aimeizi.javaconfig.example;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+public class App {
+
+ @SuppressWarnings("resource")
+ public static void main(String[] args) {
+
+ /**
+ * Create a new ApplicationContext, deriving bean definition from the
+ * given annotated class and automatically refreshing the context.
+ */
+ ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
+ /**
+ * Return an instance, which may be shared or independent, of the
+ * specified bean.
+ */
+ HelloWorldService obj = (HelloWorldService) context.getBean("helloWorldBean");
+ obj.setName("Spring 3.2.3");
+ obj.sayHello();
+
+ }
+
+}
diff --git a/spring3-javaconfig-example/src/main/java/net/aimeizi/javaconfig/example/AppConfig.java b/spring3-javaconfig-example/src/main/java/net/aimeizi/javaconfig/example/AppConfig.java
new file mode 100644
index 0000000..47887f7
--- /dev/null
+++ b/spring3-javaconfig-example/src/main/java/net/aimeizi/javaconfig/example/AppConfig.java
@@ -0,0 +1,14 @@
+package net.aimeizi.javaconfig.example;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class AppConfig {
+
+ @Bean(name="helloWorldBean")
+ public HelloWorldService helloWorldService() {
+ return new HelloWorldService();
+ }
+
+}
diff --git a/spring3-javaconfig-example/src/main/java/net/aimeizi/javaconfig/example/HelloWorldService.java b/spring3-javaconfig-example/src/main/java/net/aimeizi/javaconfig/example/HelloWorldService.java
new file mode 100644
index 0000000..9942f44
--- /dev/null
+++ b/spring3-javaconfig-example/src/main/java/net/aimeizi/javaconfig/example/HelloWorldService.java
@@ -0,0 +1,19 @@
+package net.aimeizi.javaconfig.example;
+
+public class HelloWorldService {
+
+ private String name;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public void sayHello() {
+ System.out.println("Hello from Java Configuration. " + this.getName());
+ }
+
+}
diff --git a/spring3-javaconfig-example/src/main/resources/applicationContext.xml b/spring3-javaconfig-example/src/main/resources/applicationContext.xml
new file mode 100644
index 0000000..5ce0381
--- /dev/null
+++ b/spring3-javaconfig-example/src/main/resources/applicationContext.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring3-javaconfig-import-example/.gitignore b/spring3-javaconfig-import-example/.gitignore
new file mode 100644
index 0000000..9dff9cc
--- /dev/null
+++ b/spring3-javaconfig-import-example/.gitignore
@@ -0,0 +1,4 @@
+/.project
+/.settings
+/target
+/.classpath
diff --git a/spring3-javaconfig-import-example/pom.xml b/spring3-javaconfig-import-example/pom.xml
new file mode 100644
index 0000000..7c51f32
--- /dev/null
+++ b/spring3-javaconfig-import-example/pom.xml
@@ -0,0 +1,33 @@
+
+ 4.0.0
+
+ net.aimeizi
+ maven-framework-project
+ 1.0.0
+
+ spring3-javaconfig-import-example
+
+
+
+ org.springframework
+ spring-core
+ ${spring.version}
+
+
+ org.springframework
+ spring-context
+ ${spring.version}
+
+
+ cglib
+ cglib
+ 3.0
+
+
+
+
+ 3.2.3.RELEASE
+
+
+
\ No newline at end of file
diff --git a/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/App.java b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/App.java
new file mode 100644
index 0000000..d2023df
--- /dev/null
+++ b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/App.java
@@ -0,0 +1,21 @@
+package net.aimeizi.javaconfig.example;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+
+public class App {
+
+ @SuppressWarnings("resource")
+ public static void main(String[] args) {
+
+ ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
+
+ HelloWorldService hello = (HelloWorldService) context.getBean("helloWorldBean");
+ hello.sayHello("Spring 3.2.3");
+
+ GoodbyeService bye = (GoodbyeService) context.getBean("goodbyeBean");
+ bye.sayGoodbye("Spring 3.2.3");
+
+ }
+
+}
diff --git a/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/AppConfig.java b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/AppConfig.java
new file mode 100644
index 0000000..a3e7e28
--- /dev/null
+++ b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/AppConfig.java
@@ -0,0 +1,10 @@
+package net.aimeizi.javaconfig.example;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+
+@Configuration
+@Import(value={HelloConfig.class,GoodbyeConfig.class})
+public class AppConfig {
+
+}
diff --git a/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/AppXml.java b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/AppXml.java
new file mode 100644
index 0000000..333d8c2
--- /dev/null
+++ b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/AppXml.java
@@ -0,0 +1,21 @@
+package net.aimeizi.javaconfig.example;
+
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class AppXml {
+
+ @SuppressWarnings("resource")
+ public static void main(String[] args) {
+
+ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
+
+ HelloWorldService hello = (HelloWorldService) context.getBean("helloWorldBean");
+ hello.sayHello("Spring 3.2.3");
+
+ GoodbyeService bye = (GoodbyeService) context.getBean("goodbyeBean");
+ bye.sayGoodbye("Spring 3.2.3");
+
+ }
+
+}
diff --git a/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/GoodbyeConfig.java b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/GoodbyeConfig.java
new file mode 100644
index 0000000..2459139
--- /dev/null
+++ b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/GoodbyeConfig.java
@@ -0,0 +1,14 @@
+package net.aimeizi.javaconfig.example;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class GoodbyeConfig {
+
+ @Bean(name="goodbyeBean")
+ public GoodbyeService goodByeService() {
+ return new GoodbyeService();
+ }
+
+}
diff --git a/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/GoodbyeService.java b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/GoodbyeService.java
new file mode 100644
index 0000000..30207df
--- /dev/null
+++ b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/GoodbyeService.java
@@ -0,0 +1,9 @@
+package net.aimeizi.javaconfig.example;
+
+public class GoodbyeService {
+
+ public void sayGoodbye(String name){
+ System.out.println("Goodbye from Java Configuration. "+ name);
+ }
+
+}
diff --git a/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/HelloConfig.java b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/HelloConfig.java
new file mode 100644
index 0000000..31e34c2
--- /dev/null
+++ b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/HelloConfig.java
@@ -0,0 +1,14 @@
+package net.aimeizi.javaconfig.example;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class HelloConfig {
+
+ @Bean(name="helloWorldBean")
+ public HelloWorldService helloWorldService() {
+ return new HelloWorldService();
+ }
+
+}
diff --git a/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/HelloWorldService.java b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/HelloWorldService.java
new file mode 100644
index 0000000..591bbb6
--- /dev/null
+++ b/spring3-javaconfig-import-example/src/main/java/net/aimeizi/javaconfig/example/HelloWorldService.java
@@ -0,0 +1,9 @@
+package net.aimeizi.javaconfig.example;
+
+public class HelloWorldService {
+
+ public void sayHello(String name) {
+ System.out.println("Hello from Java Configuration. " + name);
+ }
+
+}
diff --git a/spring3-javaconfig-import-example/src/main/resources/applicationContext.xml b/spring3-javaconfig-import-example/src/main/resources/applicationContext.xml
new file mode 100644
index 0000000..530595d
--- /dev/null
+++ b/spring3-javaconfig-import-example/src/main/resources/applicationContext.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring3-javaconfig-import-example/src/main/resources/goodbye.xml b/spring3-javaconfig-import-example/src/main/resources/goodbye.xml
new file mode 100644
index 0000000..cbc5959
--- /dev/null
+++ b/spring3-javaconfig-import-example/src/main/resources/goodbye.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring3-javaconfig-import-example/src/main/resources/hello.xml b/spring3-javaconfig-import-example/src/main/resources/hello.xml
new file mode 100644
index 0000000..6ba9341
--- /dev/null
+++ b/spring3-javaconfig-import-example/src/main/resources/hello.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring3-jmx-example/.gitignore b/spring3-jmx-example/.gitignore
new file mode 100644
index 0000000..7075a2f
--- /dev/null
+++ b/spring3-jmx-example/.gitignore
@@ -0,0 +1,4 @@
+/target
+/.classpath
+/.project
+/.settings
diff --git a/spring3-jmx-example/README.md b/spring3-jmx-example/README.md
new file mode 100644
index 0000000..061831e
--- /dev/null
+++ b/spring3-jmx-example/README.md
@@ -0,0 +1,20 @@
+# spring3-jmx-example
+
+copy jmxremote.access jmxremote.password
+
+service:jmx:rmi://localhost/jndi/rmi://localhost:8888/jemosJmxConnector
+
+jemosAdmin / secure
+
+
+
+
+
+
+
+
+* [http://www.javacodegeeks.com/2012/07/jmx-and-spring-part-1.html](http://www.javacodegeeks.com/2012/07/jmx-and-spring-part-1.html)
+
+* [http://www.javacodegeeks.com/2012/07/jmx-and-spring-part-2.html](http://www.javacodegeeks.com/2012/07/jmx-and-spring-part-2.html)
+
+* [http://www.javacodegeeks.com/2012/07/jmx-and-spring-part-3.html](http://www.javacodegeeks.com/2012/07/jmx-and-spring-part-3.html)
\ No newline at end of file
diff --git a/spring3-jmx-example/pom.xml b/spring3-jmx-example/pom.xml
new file mode 100644
index 0000000..e96d41c
--- /dev/null
+++ b/spring3-jmx-example/pom.xml
@@ -0,0 +1,95 @@
+
+ 4.0.0
+
+ net.aimeizi
+ maven-framework-project
+ 1.0.0
+
+ net.aimeizi.jmx.example
+ spring3-jmx-example
+
+
+
+ junit
+ junit
+ 4.8.2
+ test
+
+
+ log4j
+ log4j
+ 1.2.16
+ compile
+
+
+ org.springframework
+ spring-context
+ 3.0.5.RELEASE
+ compile
+
+
+ org.springframework
+ spring-core
+ 3.0.5.RELEASE
+ compile
+
+
+ org.springframework
+ spring-jmx
+ 2.0.8
+ compile
+
+
+ org.springframework
+ spring-test
+ 3.0.5.RELEASE
+ jar
+ test
+
+
+ javax.annotation
+ jsr250-api
+ 1.0
+
+
+ commons-io
+ commons-io
+ 2.0.1
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 2.3.2
+
+ 1.7
+ 1.7
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 2.2.1
+
+
+ buildable-project
+ install
+
+ assembly
+
+
+
+
+
+ project
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/SystemConfig.java b/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/SystemConfig.java
new file mode 100644
index 0000000..5aad4aa
--- /dev/null
+++ b/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/SystemConfig.java
@@ -0,0 +1,41 @@
+package net.aimeizi.jmx.example;
+
+public class SystemConfig implements SystemConfigMBean {
+
+ private int threadCount;
+ private String schemaName;
+
+ public SystemConfig(int numThreads, String schema){
+ this.threadCount=numThreads;
+ this.schemaName=schema;
+ }
+
+ @Override
+ public void setThreadCount(int noOfThreads) {
+ this.threadCount=noOfThreads;
+ }
+
+
+ @Override
+ public int getThreadCount() {
+ return this.threadCount;
+ }
+
+
+ @Override
+ public void setSchemaName(String schemaName) {
+ this.schemaName=schemaName;
+ }
+
+
+ @Override
+ public String getSchemaName() {
+ return this.schemaName;
+ }
+
+ @Override
+ public String doConfig(){
+ return "No of Threads="+this.threadCount+" and DB Schema Name="+this.schemaName;
+ }
+
+}
\ No newline at end of file
diff --git a/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/SystemConfigMBean.java b/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/SystemConfigMBean.java
new file mode 100644
index 0000000..2e31062
--- /dev/null
+++ b/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/SystemConfigMBean.java
@@ -0,0 +1,15 @@
+package net.aimeizi.jmx.example;
+
+public interface SystemConfigMBean {
+
+ public void setThreadCount(int noOfThreads);
+
+ public int getThreadCount();
+
+ public void setSchemaName(String schemaName);
+
+ public String getSchemaName();
+
+ public String doConfig();
+
+}
diff --git a/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/SystemConfigManagement.java b/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/SystemConfigManagement.java
new file mode 100644
index 0000000..514dea3
--- /dev/null
+++ b/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/SystemConfigManagement.java
@@ -0,0 +1,30 @@
+package net.aimeizi.jmx.example;
+
+import java.lang.management.ManagementFactory;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+
+public class SystemConfigManagement {
+ private static final int DEFAULT_NO_THREADS=10;
+ private static final String DEFAULT_SCHEMA="default";
+
+ public static void main(String[] args) throws MalformedObjectNameException, InterruptedException, InstanceAlreadyExistsException, MBeanRegistrationException, NotCompliantMBeanException {
+ //Get the MBean server
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ //register the MBean
+ SystemConfig mBean = new SystemConfig(DEFAULT_NO_THREADS, DEFAULT_SCHEMA);
+ ObjectName name = new ObjectName("net.aimeizi.jmx.example:type=SystemConfig");
+ mbs.registerMBean(mBean, name);
+ do{
+ Thread.sleep(3000);
+ System.out.println("Thread Count="+mBean.getThreadCount()+":::Schema Name="+mBean.getSchemaName());
+ }while(mBean.getThreadCount() !=0);
+
+ }
+
+}
\ No newline at end of file
diff --git a/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/TomcatJMX.java b/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/TomcatJMX.java
new file mode 100644
index 0000000..c2180e2
--- /dev/null
+++ b/spring3-jmx-example/src/main/java/net/aimeizi/jmx/example/TomcatJMX.java
@@ -0,0 +1,171 @@
+package net.aimeizi.jmx.example;
+
+import java.lang.management.MemoryUsage;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Formatter;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectInstance;
+import javax.management.ObjectName;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+
+/**
+ * 使用JMX监控Tomcat
+ * @author welcome
+ *
+ */
+public class TomcatJMX {
+
+ @SuppressWarnings({ "rawtypes", "unused" })
+ public static void main(String[] args) {
+ try {
+
+ String jmxURL = "service:jmx:rmi:///jndi/rmi://127.0.0.1:8999/jmxrmi";
+
+ JMXServiceURL serviceURL = new JMXServiceURL(jmxURL);
+
+ Map map = new HashMap();
+ String[] credentials = new String[] { "monitorRole", "admin" };
+ map.put("jmx.remote.credentials", credentials);
+ JMXConnector connector = JMXConnectorFactory.connect(serviceURL,map);
+ MBeanServerConnection mbsc = connector.getMBeanServerConnection();
+
+ // 端口最好是动态取得
+ ObjectName threadObjName = new ObjectName(
+ "Catalina:type=ThreadPool,name=http-8080");
+ MBeanInfo mbInfo = mbsc.getMBeanInfo(threadObjName);
+
+ String attrName = "currentThreadCount";// tomcat的线程数对应的属性值
+ MBeanAttributeInfo[] mbAttributes = mbInfo.getAttributes();
+ System.out.println("currentThreadCount:"+ mbsc.getAttribute(threadObjName, attrName));
+
+ // heap
+ for (int j = 0; j < mbsc.getDomains().length; j++) {
+ System.out.println("###########" + mbsc.getDomains()[j]);
+ }
+ Set MBeanset = mbsc.queryMBeans(null, null);
+ System.out.println("MBeanset.size() : " + MBeanset.size());
+ Iterator MBeansetIterator = MBeanset.iterator();
+ while (MBeansetIterator.hasNext()) {
+ ObjectInstance objectInstance = (ObjectInstance) MBeansetIterator.next();
+ ObjectName objectName = objectInstance.getObjectName();
+ String canonicalName = objectName.getCanonicalName();
+ System.out.println("canonicalName : " + canonicalName);
+ if (canonicalName
+ .equals("Catalina:host=localhost,type=Cluster")) {
+ // Get details of cluster MBeans
+ System.out.println("Cluster MBeans Details:");
+ System.out
+ .println("=========================================");
+ // getMBeansDetails(canonicalName);
+ String canonicalKeyPropList = objectName.getCanonicalKeyPropertyListString();
+ }
+ }
+ // ------------------------- system ----------------------
+ ObjectName runtimeObjName = new ObjectName("java.lang:type=Runtime");
+ System.out.println("厂商:"
+ + (String) mbsc.getAttribute(runtimeObjName, "VmVendor"));
+ System.out.println("程序:"
+ + (String) mbsc.getAttribute(runtimeObjName, "VmName"));
+ System.out.println("版本:"
+ + (String) mbsc.getAttribute(runtimeObjName, "VmVersion"));
+ Date starttime = new Date((Long) mbsc.getAttribute(runtimeObjName,
+ "StartTime"));
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ System.out.println("启动时间:" + df.format(starttime));
+
+ Long timespan = (Long) mbsc.getAttribute(runtimeObjName, "Uptime");
+ System.out.println("连续工作时间:" + TomcatJMX.formatTimeSpan(timespan));
+ // ------------------------ JVM -------------------------
+ // 堆使用率
+ ObjectName heapObjName = new ObjectName("java.lang:type=Memory");
+ MemoryUsage heapMemoryUsage = MemoryUsage
+ .from((CompositeDataSupport) mbsc.getAttribute(heapObjName,
+ "HeapMemoryUsage"));
+ long maxMemory = heapMemoryUsage.getMax();// 堆最大
+ long commitMemory = heapMemoryUsage.getCommitted();// 堆当前分配
+ long usedMemory = heapMemoryUsage.getUsed();
+ System.out.println("heap:" + (double) usedMemory * 100
+ / commitMemory + "%");// 堆使用率
+
+ MemoryUsage nonheapMemoryUsage = MemoryUsage
+ .from((CompositeDataSupport) mbsc.getAttribute(heapObjName,
+ "NonHeapMemoryUsage"));
+ long noncommitMemory = nonheapMemoryUsage.getCommitted();
+ long nonusedMemory = heapMemoryUsage.getUsed();
+ System.out.println("nonheap:" + (double) nonusedMemory * 100
+ / noncommitMemory + "%");
+
+ ObjectName permObjName = new ObjectName(
+ "java.lang:type=MemoryPool,name=Perm Gen");
+ MemoryUsage permGenUsage = MemoryUsage
+ .from((CompositeDataSupport) mbsc.getAttribute(permObjName,
+ "Usage"));
+ long committed = permGenUsage.getCommitted();// 持久堆大小
+ long used = heapMemoryUsage.getUsed();//
+ System.out.println("perm gen:" + (double) used * 100 / committed
+ + "%");// 持久堆使用率
+
+ // -------------------- Session ---------------
+ ObjectName managerObjName = new ObjectName(
+ "Catalina:type=Manager,*");
+ Set s = mbsc.queryNames(managerObjName, null);
+ for (ObjectName obj : s) {
+ System.out.println("应用名:" + obj.getKeyProperty("path"));
+ ObjectName objname = new ObjectName(obj.getCanonicalName());
+ System.out.println("最大会话数:"
+ + mbsc.getAttribute(objname, "maxActiveSessions"));
+ System.out.println("会话数:"
+ + mbsc.getAttribute(objname, "activeSessions"));
+ System.out.println("活动会话数:"
+ + mbsc.getAttribute(objname, "sessionCounter"));
+ }
+
+ // ----------------- Thread Pool ----------------
+ ObjectName threadpoolObjName = new ObjectName(
+ "Catalina:type=ThreadPool,*");
+ Set s2 = mbsc.queryNames(threadpoolObjName, null);
+ for (ObjectName obj : s2) {
+ System.out.println("端口名:" + obj.getKeyProperty("name"));
+ ObjectName objname = new ObjectName(obj.getCanonicalName());
+ System.out.println("最大线程数:"
+ + mbsc.getAttribute(objname, "maxThreads"));
+ System.out.println("当前线程数:"
+ + mbsc.getAttribute(objname, "currentThreadCount"));
+ System.out.println("繁忙线程数:"
+ + mbsc.getAttribute(objname, "currentThreadsBusy"));
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ @SuppressWarnings({"resource" })
+ public static String formatTimeSpan(long span) {
+ long minseconds = span % 1000;
+
+ span = span / 1000;
+ long seconds = span % 60;
+
+ span = span / 60;
+ long mins = span % 60;
+
+ span = span / 60;
+ long hours = span % 24;
+
+ span = span / 24;
+ long days = span;
+ return (new Formatter()).format("%1$d天 %2$02d:%3$02d:%4$02d.%5$03d",days, hours, mins, seconds, minseconds).toString();
+ }
+}
\ No newline at end of file
diff --git a/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemTest.java b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemTest.java
new file mode 100644
index 0000000..b307aff
--- /dev/null
+++ b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemTest.java
@@ -0,0 +1,11 @@
+package uk.co.jemos.experiments.jmx;
+
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class MemTest {
+ public static void main(String[] args) {
+
+ new ClassPathXmlApplicationContext("classpath:jemos-jmx-appCtx.xml");
+
+ }
+}
\ No newline at end of file
diff --git a/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemoryHeapFiller.java b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemoryHeapFiller.java
new file mode 100644
index 0000000..368b96e
--- /dev/null
+++ b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemoryHeapFiller.java
@@ -0,0 +1,22 @@
+package uk.co.jemos.experiments.jmx;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+@Component
+public class MemoryHeapFiller {
+
+ private static final Collection GARBAGE = new ArrayList();
+
+ @Scheduled(fixedDelay = 2000)
+ public void addGarbage() {
+ System.out.println("Adding data...");
+ for (int i = 0; i < 1000000; i++) {
+ GARBAGE.add(Math.random());
+ }
+ }
+
+}
diff --git a/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemoryThreadDumper.java b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemoryThreadDumper.java
new file mode 100644
index 0000000..8ec67d1
--- /dev/null
+++ b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemoryThreadDumper.java
@@ -0,0 +1,119 @@
+package uk.co.jemos.experiments.jmx;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.io.IOUtils;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author mtedone
+ *
+ */
+@Component
+public class MemoryThreadDumper {
+
+ // ------------------->> Constants
+
+ /** The application logger */
+ private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger
+ .getLogger(MemoryThreadDumper.class);
+
+ // ------------------->> Instance / Static variables
+
+ // ------------------->> Constructors
+
+ // ------------------->> Public methods
+
+ /**
+ * It dumps the Thread stacks
+ *
+ * @throws IOException
+ */
+ public void dumpStacks() {
+
+ // choose our dump-file
+ String stackFileName = "C:/tmp/stacks.dump";
+
+ ThreadMXBean mxBean = ManagementFactory.getThreadMXBean();
+ ThreadInfo[] threadInfos = mxBean.getThreadInfo(
+ mxBean.getAllThreadIds(), 0);
+ Map threadInfoMap = new HashMap();
+ for (ThreadInfo threadInfo : threadInfos) {
+ threadInfoMap.put(threadInfo.getThreadId(), threadInfo);
+ }
+
+ File dumpFile = new File(stackFileName);
+ BufferedWriter writer = null;
+ try {
+ writer = new BufferedWriter(new FileWriter(dumpFile));
+ this.dumpTraces(mxBean, threadInfoMap, writer);
+
+ LOG.warn("Stacks dumped to: " + stackFileName);
+
+ } catch (IOException e) {
+ throw new IllegalStateException(
+ "An exception occurred while writing the thread dump");
+ } finally {
+ IOUtils.closeQuietly(writer);
+ }
+
+ }
+
+ // ------------------->> Getters / Setters
+
+ // ------------------->> Private methods
+
+ private void dumpTraces(ThreadMXBean mxBean,
+ Map threadInfoMap, Writer writer)
+ throws IOException {
+ Map stacks = Thread.getAllStackTraces();
+ writer.write("Dump of "
+ + stacks.size()
+ + " thread at "
+ + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss z")
+ .format(new Date(System.currentTimeMillis())) + "\n\n");
+ for (Map.Entry entry : stacks.entrySet()) {
+ Thread thread = entry.getKey();
+ writer.write("\"" + thread.getName() + "\" prio="
+ + thread.getPriority() + " tid=" + thread.getId() + " "
+ + thread.getState() + " "
+ + (thread.isDaemon() ? "deamon" : "worker") + "\n");
+ ThreadInfo threadInfo = threadInfoMap.get(thread.getId());
+ if (threadInfo != null) {
+ writer.write(" native=" + threadInfo.isInNative()
+ + ", suspended=" + threadInfo.isSuspended()
+ + ", block=" + threadInfo.getBlockedCount() + ", wait="
+ + threadInfo.getWaitedCount() + "\n");
+ writer.write(" lock=" + threadInfo.getLockName()
+ + " owned by " + threadInfo.getLockOwnerName() + " ("
+ + threadInfo.getLockOwnerId() + "), cpu="
+ + mxBean.getThreadCpuTime(threadInfo.getThreadId())
+ / 1000000L + ", user="
+ + mxBean.getThreadUserTime(threadInfo.getThreadId())
+ / 1000000L + "\n");
+ }
+ for (StackTraceElement element : entry.getValue()) {
+ writer.write(" ");
+ writer.write(element.toString());
+ writer.write("\n");
+ }
+ writer.write("\n");
+ }
+ }
+
+ // ------------------->> equals() / hashcode() / toString()
+
+ // ------------------->> Inner classes
+
+}
diff --git a/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemoryWarningService.java b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemoryWarningService.java
new file mode 100644
index 0000000..1fceee3
--- /dev/null
+++ b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/MemoryWarningService.java
@@ -0,0 +1,116 @@
+package uk.co.jemos.experiments.jmx;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryNotificationInfo;
+import java.lang.management.MemoryPoolMXBean;
+import java.lang.management.MemoryType;
+
+import javax.annotation.PostConstruct;
+import javax.management.Notification;
+import javax.management.NotificationEmitter;
+import javax.management.NotificationListener;
+
+import org.springframework.beans.factory.annotation.Autowired;
+
+/**
+ * A component which sends notifications when the HEAP memory is above a certain
+ * threshold.
+ *
+ * @author mtedone
+ *
+ */
+public class MemoryWarningService implements NotificationListener {
+
+ // ------------------->> Constants
+
+ /** This bean's name */
+ public static final String MBEAN_NAME = "jemos.mbeans:type=monitoring,name=MemoryWarningService";
+
+ /** The application logger */
+ private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger
+ .getLogger(MemoryWarningService.class);
+
+ @Autowired
+ private NotificationEmitter memoryMxBean;
+
+ @Autowired
+ private MemoryThreadDumper threadDumper;
+
+ // ------------------->> Instance / Static variables
+
+ /** A pool of Memory MX Beans specialised in HEAP management */
+ private static final MemoryPoolMXBean tenuredGenPool = findTenuredGenPool();
+
+ // ------------------->> Constructors
+
+ // ------------------->> Public methods
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleNotification(Notification notification, Object handback) {
+
+ if (notification.getType().equals(
+ MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED)) {
+ long maxMemory = tenuredGenPool.getUsage().getMax();
+ long usedMemory = tenuredGenPool.getUsage().getUsed();
+ LOG.warn("Memory usage low!!!");
+ double percentageUsed = (double) usedMemory / maxMemory;
+ LOG.warn("percentageUsed = " + percentageUsed);
+ threadDumper.dumpStacks();
+
+ } else {
+ LOG.info("Other notification received..."
+ + notification.getMessage());
+ }
+
+ }
+
+ // ------------------->> Getters / Setters
+
+ /**
+ * It sets the threshold percentage.
+ *
+ * @param percentage
+ */
+ public void setPercentageUsageThreshold(double percentage) {
+ if (percentage <= 0.0 || percentage > 1.0) {
+ throw new IllegalArgumentException("Percentage not in range");
+ } else {
+ LOG.info("Percentage is: " + percentage);
+ }
+ long maxMemory = tenuredGenPool.getUsage().getMax();
+ long warningThreshold = (long) (maxMemory * percentage);
+ tenuredGenPool.setUsageThreshold(warningThreshold);
+ }
+
+ @PostConstruct
+ public void completeSetup() {
+ memoryMxBean.addNotificationListener(this, null, null);
+ LOG.info("Listener added to JMX bean");
+ }
+
+ // ------------------->> Private methods
+
+ /**
+ * Tenured Space Pool can be determined by it being of type HEAP and by it
+ * being possible to set the usage threshold.
+ */
+ private static MemoryPoolMXBean findTenuredGenPool() {
+ for (MemoryPoolMXBean pool : ManagementFactory.getMemoryPoolMXBeans()) {
+ // I don't know whether this approach is better, or whether
+ // we should rather check for the pool name "Tenured Gen"?
+ if (pool.getType() == MemoryType.HEAP
+ && pool.isUsageThresholdSupported()) {
+ return pool;
+ }
+ }
+ throw new AssertionError("Could not find tenured space");
+ }
+
+ // ------------------->> equals() / hashcode() / toString()
+
+ // ------------------->> Inner classes
+
+}
diff --git a/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/mbeans/LoggerConfigurator.java b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/mbeans/LoggerConfigurator.java
new file mode 100644
index 0000000..7dc669c
--- /dev/null
+++ b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/mbeans/LoggerConfigurator.java
@@ -0,0 +1,71 @@
+package uk.co.jemos.experiments.jmx.mbeans;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.springframework.jmx.export.annotation.ManagedOperation;
+import org.springframework.jmx.export.annotation.ManagedOperationParameter;
+import org.springframework.jmx.export.annotation.ManagedOperationParameters;
+import org.springframework.jmx.export.annotation.ManagedResource;
+import org.springframework.stereotype.Component;
+
+/**
+ * MBean which allows clients to change or retrieve the logging level for a
+ * Log4j Logger at runtime.
+ *
+ * @author mtedone
+ *
+ */
+@Component
+@ManagedResource(objectName = LoggerConfigurator.MBEAN_NAME, //
+description = "Allows clients to set the Log4j Logger level at runtime")
+public class LoggerConfigurator {
+
+ // ------------------->> Constants
+
+ public static final String MBEAN_NAME = "jemos.mbeans:type=config,name=LoggingConfiguration";
+
+ // ------------------->> Instance / Static variables
+
+ // ------------------->> Constructors
+
+ // ------------------->> Public methods
+
+ @ManagedOperation(description = "Returns the Logger LEVEL for the given logger name")
+ @ManagedOperationParameters({ @ManagedOperationParameter(description = "The Logger Name", name = "loggerName"), })
+ public String getLoggerLevel(String loggerName) {
+
+ Logger logger = Logger.getLogger(loggerName);
+ Level loggerLevel = logger.getLevel();
+
+ return loggerLevel == null ? "The logger " + loggerName
+ + " has not level" : loggerLevel.toString();
+
+ }
+
+ @ManagedOperation(description = "Set Logger Level")
+ @ManagedOperationParameters({
+ @ManagedOperationParameter(description = "The Logger Name", name = "loggerName"),
+ @ManagedOperationParameter(description = "The Level to which the Logger must be set", name = "loggerLevel") })
+ public void setLoggerLevel(String loggerName, String loggerLevel) {
+
+ Logger thisLogger = Logger.getLogger(this.getClass());
+ thisLogger.setLevel(Level.INFO);
+
+ Logger logger = Logger.getLogger(loggerName);
+
+ logger.setLevel(Level.toLevel(loggerLevel, Level.INFO));
+
+ thisLogger.info("Set logger " + loggerName + " to level "
+ + logger.getLevel());
+
+ }
+
+ // ------------------->> Getters / Setters
+
+ // ------------------->> Private methods
+
+ // ------------------->> equals() / hashcode() / toString()
+
+ // ------------------->> Inner classes
+
+}
diff --git a/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/mbeans/MemoryWarningServiceConfigurator.java b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/mbeans/MemoryWarningServiceConfigurator.java
new file mode 100644
index 0000000..0df6500
--- /dev/null
+++ b/spring3-jmx-example/src/main/java/uk/co/jemos/experiments/jmx/mbeans/MemoryWarningServiceConfigurator.java
@@ -0,0 +1,62 @@
+package uk.co.jemos.experiments.jmx.mbeans;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.jmx.export.annotation.ManagedOperation;
+import org.springframework.jmx.export.annotation.ManagedOperationParameter;
+import org.springframework.jmx.export.annotation.ManagedOperationParameters;
+import org.springframework.jmx.export.annotation.ManagedResource;
+import org.springframework.stereotype.Component;
+
+import uk.co.jemos.experiments.jmx.MemoryWarningService;
+
+@Component
+@ManagedResource(objectName = MemoryWarningServiceConfigurator.MBEAN_NAME, //
+description = "Allows clients to set the memory threshold")
+public class MemoryWarningServiceConfigurator implements
+ ApplicationContextAware {
+
+ // ------------------->> Constants
+
+ /** The application logger */
+ private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger
+ .getLogger(MemoryWarningServiceConfigurator.class);
+
+ public static final String MBEAN_NAME = "jemos.mbeans:type=config,name=MemoryWarningServiceConfiguration";
+
+ private ApplicationContext ctx;
+
+ // ------------------->> Instance / Static variables
+
+ // ------------------->> Constructors
+
+ // ------------------->> Public methods
+
+ @ManagedOperation(description = "Sets the memory threshold for the memory warning system")
+ @ManagedOperationParameters({ @ManagedOperationParameter(description = "The memory threshold", name = "memoryThreshold"), })
+ public void setMemoryThreshold(double memoryThreshold) {
+
+ MemoryWarningService memoryWarningService = (MemoryWarningService) ctx
+ .getBean("memoryWarningService");
+ memoryWarningService.setPercentageUsageThreshold(memoryThreshold);
+
+ LOG.info("Memory threshold set to " + memoryThreshold);
+ }
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext)
+ throws BeansException {
+ ctx = applicationContext;
+
+ }
+
+ // ------------------->> Getters / Setters
+
+ // ------------------->> Private methods
+
+ // ------------------->> equals() / hashcode() / toString()
+
+ // ------------------->> Inner classes
+
+}
diff --git a/spring3-jmx-example/src/main/resources/jemos-jmx-appCtx.xml b/spring3-jmx-example/src/main/resources/jemos-jmx-appCtx.xml
new file mode 100644
index 0000000..3602d56
--- /dev/null
+++ b/spring3-jmx-example/src/main/resources/jemos-jmx-appCtx.xml
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+ classpath:jemos-jmx.properties
+ classpath:jmxconnector-credentials.properties
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring3-jmx-example/src/main/resources/jemos-jmx-appCtxImpl.xml b/spring3-jmx-example/src/main/resources/jemos-jmx-appCtxImpl.xml
new file mode 100644
index 0000000..9409861
--- /dev/null
+++ b/spring3-jmx-example/src/main/resources/jemos-jmx-appCtxImpl.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/spring3-jmx-example/src/main/resources/jemos-jmx-experiments-0.0.1-snapshot-project.zip b/spring3-jmx-example/src/main/resources/jemos-jmx-experiments-0.0.1-snapshot-project.zip
new file mode 100644
index 0000000..0583dbe
Binary files /dev/null and b/spring3-jmx-example/src/main/resources/jemos-jmx-experiments-0.0.1-snapshot-project.zip differ
diff --git a/spring3-jmx-example/src/main/resources/jemos-jmx.properties b/spring3-jmx-example/src/main/resources/jemos-jmx.properties
new file mode 100644
index 0000000..0b5b109
--- /dev/null
+++ b/spring3-jmx-example/src/main/resources/jemos-jmx.properties
@@ -0,0 +1 @@
+jemos.jmx.rmi.port=8888
\ No newline at end of file
diff --git a/spring3-jmx-example/src/main/resources/jmx-1.jpg b/spring3-jmx-example/src/main/resources/jmx-1.jpg
new file mode 100644
index 0000000..7c59804
Binary files /dev/null and b/spring3-jmx-example/src/main/resources/jmx-1.jpg differ
diff --git a/spring3-jmx-example/src/main/resources/jmx-2.jpg b/spring3-jmx-example/src/main/resources/jmx-2.jpg
new file mode 100644
index 0000000..3cdc7b6
Binary files /dev/null and b/spring3-jmx-example/src/main/resources/jmx-2.jpg differ
diff --git a/spring3-jmx-example/src/main/resources/jmx-3.jpg b/spring3-jmx-example/src/main/resources/jmx-3.jpg
new file mode 100644
index 0000000..68bda79
Binary files /dev/null and b/spring3-jmx-example/src/main/resources/jmx-3.jpg differ
diff --git a/spring3-jmx-example/src/main/resources/jmx-tomcat-1.jpg b/spring3-jmx-example/src/main/resources/jmx-tomcat-1.jpg
new file mode 100644
index 0000000..1d7f9e2
Binary files /dev/null and b/spring3-jmx-example/src/main/resources/jmx-tomcat-1.jpg differ
diff --git a/spring3-jmx-example/src/main/resources/jmx-tomcat-2.jpg b/spring3-jmx-example/src/main/resources/jmx-tomcat-2.jpg
new file mode 100644
index 0000000..c7699aa
Binary files /dev/null and b/spring3-jmx-example/src/main/resources/jmx-tomcat-2.jpg differ
diff --git a/spring3-jmx-example/src/main/resources/jmx-tomcat-3.jpg b/spring3-jmx-example/src/main/resources/jmx-tomcat-3.jpg
new file mode 100644
index 0000000..878d872
Binary files /dev/null and b/spring3-jmx-example/src/main/resources/jmx-tomcat-3.jpg differ
diff --git a/spring3-jmx-example/src/main/resources/jmx-tomcat-4.jpg b/spring3-jmx-example/src/main/resources/jmx-tomcat-4.jpg
new file mode 100644
index 0000000..cecc461
Binary files /dev/null and b/spring3-jmx-example/src/main/resources/jmx-tomcat-4.jpg differ
diff --git a/spring3-jmx-example/src/main/resources/jmxconnector-credentials.properties b/spring3-jmx-example/src/main/resources/jmxconnector-credentials.properties
new file mode 100644
index 0000000..d378df8
--- /dev/null
+++ b/spring3-jmx-example/src/main/resources/jmxconnector-credentials.properties
@@ -0,0 +1,2 @@
+jmx.username=jemosAdmin
+jmx.password=secure
\ No newline at end of file
diff --git a/spring3-jmx-example/src/main/resources/jmxremote.access b/spring3-jmx-example/src/main/resources/jmxremote.access
new file mode 100644
index 0000000..339402c
--- /dev/null
+++ b/spring3-jmx-example/src/main/resources/jmxremote.access
@@ -0,0 +1 @@
+jemosAdmin readwrite
\ No newline at end of file
diff --git a/spring3-jmx-example/src/main/resources/jmxremote.password b/spring3-jmx-example/src/main/resources/jmxremote.password
new file mode 100644
index 0000000..45587f8
--- /dev/null
+++ b/spring3-jmx-example/src/main/resources/jmxremote.password
@@ -0,0 +1 @@
+jemosAdmin secure
\ No newline at end of file
diff --git a/spring3-jmx-example/src/main/resources/log4j.properties b/spring3-jmx-example/src/main/resources/log4j.properties
new file mode 100644
index 0000000..2876335
--- /dev/null
+++ b/spring3-jmx-example/src/main/resources/log4j.properties
@@ -0,0 +1,7 @@
+log4j.rootCategory=INFO, S
+
+log4j.logger.uk.co.jemos.experiments=INFO
+
+log4j.appender.S = org.apache.log4j.ConsoleAppender
+log4j.appender.S.layout = org.apache.log4j.PatternLayout
+log4j.appender.S.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} %c{1} [%p] %m%n
\ No newline at end of file
diff --git a/spring3-jmx-example/src/test/java/uk/co/jemos/experiments/jmx/test/system/JmxStartupSystemTest.java b/spring3-jmx-example/src/test/java/uk/co/jemos/experiments/jmx/test/system/JmxStartupSystemTest.java
new file mode 100644
index 0000000..3e75068
--- /dev/null
+++ b/spring3-jmx-example/src/test/java/uk/co/jemos/experiments/jmx/test/system/JmxStartupSystemTest.java
@@ -0,0 +1,59 @@
+package uk.co.jemos.experiments.jmx.test.system;
+
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+
+import junit.framework.Assert;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
+
+import uk.co.jemos.experiments.jmx.mbeans.LoggerConfigurator;
+
+/**
+ * System test to test the JMX server startup
+ *
+ * @author mtedone
+ *
+ */
+@ContextConfiguration(locations = { "classpath:jemos-jmx-test-appCtxImpl.xml" })
+public class JmxStartupSystemTest extends AbstractJUnit4SpringContextTests {
+
+ // ------------------->> Constants
+
+ // ------------------->> Instance / Static variables
+
+ @Autowired
+ private MBeanServerConnection mbeanClient;
+
+ // ------------------->> Constructors
+
+ // ------------------->> Public methods
+
+ @Before
+ public void init() {
+ Assert.assertNotNull("The MBean Server client cannot be null!");
+ Assert.assertNotNull("The Memory MX Bean cannot be null!");
+ }
+
+ @Test
+ public void helloWorld() throws Exception {
+
+ ObjectName objectName = new ObjectName(LoggerConfigurator.MBEAN_NAME);
+ mbeanClient.invoke(objectName, "setLoggerLevel", new Object[] {
+ "uk.co.jemos.experiments", "TRACE" }, new String[] {
+ String.class.getName(), String.class.getName() });
+
+ }
+ // ------------------->> Getters / Setters
+
+ // ------------------->> Private methods
+
+ // ------------------->> equals() / hashcode() / toString()
+
+ // ------------------->> Inner classes
+
+}
diff --git a/spring3-jmx-example/src/test/resources/jemos-jmx-test-appCtxImpl.xml b/spring3-jmx-example/src/test/resources/jemos-jmx-test-appCtxImpl.xml
new file mode 100644
index 0000000..de93956
--- /dev/null
+++ b/spring3-jmx-example/src/test/resources/jemos-jmx-test-appCtxImpl.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
diff --git a/spring3-jmx-example/使用JMX监控Tomcat.md b/spring3-jmx-example/使用JMX监控Tomcat.md
new file mode 100644
index 0000000..624e546
--- /dev/null
+++ b/spring3-jmx-example/使用JMX监控Tomcat.md
@@ -0,0 +1,84 @@
+# 使用JMX监控Tomcat
+
+## 1. 激活Tomcat的JMX远程配置
+
+要通过JMX远程监控Tomcat,首先需要激活Tomcat的JMX远程配置。
+
+① 先修改Tomcat的启动脚本,windows下为bin/catalina.bat(linux下为catalina.sh),添加以下内容,8999是jmxremote使用的端口号,第二个false表示不需要鉴权:
+
+```bash
+set JMX_REMOTE_CONFIG=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
+set CATALINA_OPTS=%CATALINA_OPTS% %JMX_REMOTE_CONFIG%
+```
+
+*要注意以上语句的位置不能太后面,可以加在【if "%OS%" == "Windows_NT" setlocal】一句后的大段的注释后面。*
+
+参考官方说明:
+
+[http://tomcat.apache.org/tomcat-6.0-doc/monitoring.html#Enabling_JMX_Remote](http://tomcat.apache.org/tomcat-6.0-doc/monitoring.html#Enabling_JMX_Remote)
+
+② 上面的配置是不需要鉴权的,如果需要鉴权则添加的内容为:
+
+```bash
+set JMX_REMOTE_CONFIG=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password -Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access
+set CATALINA_OPTS=%CATALINA_OPTS% %JMX_REMOTE_CONFIG%
+```
+
+③ 然后复制并修改授权文件
+
+$JAVA_HOME/jre/lib/management下有jmxremote.access和jmxremote.password的模板文件,将两个文件复制到$CATALINA_BASE/conf目录下
+
+◆ 修改$CATALINA_BASE/conf/jmxremote.access 添加内容:
+ monitorRole readonly
+ controlRole readwrite
+
+◆ 修改$CATALINA_BASE/conf/jmxremote.password 添加内容:
+ monitorRole admin
+ controlRole admin
+
+注意: 如果进行了以上步骤导致Tomcat启动不了,那么很可能是密码文件的权限问题
+
+需要修改jmxremote.password文件的访问权限,只有运行Tomcat的用户才能拥有访问权限 :
+ Windows的NTFS文件系统下,选中文件,点右键 -->“属性”-->“安全”--> 点“高级”--> 点“更改权限”--> 去掉“从父项继承....”--> 弹出窗口中选“删除”,这样就删除了所有访问权限。再选“添加”--> “高级”--> “立即查找”,选中你的用户(或用户组,如果选用户不行那就选用户组),例administrator,点“确定",“确定"。来到权限项目窗口,勾选“完全控制”,点“确定”,OK了。
+
+官方的提示:
+ The password file should be read-only and only accessible by the operating system user Tomcat is running as.
+
+④ 重新启动Tomcat,在Windows命令行输入“netstat -a”查看配置的端口号是否已打开,如果打开,说明上面的配置成功了。
+
+⑤ 使用jconsole测试JMX。
+
+运行$JAVA_HOME/bin目录下的jconsole.exe,打开J2SE监视和管理控制台,然后建立连接,如果是本地的Tomcat则直接选择然后点击连接,如果是远程的,则进入远程选项卡,填写地址、端口号、用户名、口令即可连接。。Mbean属性页中给出了相应的数据,Catalina中是tomcat的,java.lang是jvm的。对于加粗的黑体属性值,需双击一下才可看内容。
+
+
+
+
+
+使用远程连接查看tomcat
+
+
+
+
+
+## 2. 使用JMX监控Tomcat示例代码
+
+```java
+String jmxURL = "service:jmx:rmi:///jndi/rmi://192.168.10.93:8999/jmxrmi";
+JMXServiceURL serviceURL = new JMXServiceURL(jmxURL);
+
+Map map = new HashMap();
+// 用户名密码,在jmxremote.password文件中查看
+String[] credentials = new String[] { "monitorRole", "admin" };
+map.put("jmx.remote.credentials", credentials);
+JMXConnector connector = JMXConnectorFactory.connect(serviceURL, map);
+MBeanServerConnection mbsc = connector.getMBeanServerConnection();
+
+// 端口最好是动态取得
+ObjectName threadObjName = new ObjectName("Catalina:type=ThreadPool,name=http-8080");
+MBeanInfo mbInfo = mbsc.getMBeanInfo(threadObjName);
+
+// tomcat的线程数对应的属性值
+String attrName = "currentThreadCount";
+MBeanAttributeInfo[] mbAttributes = mbInfo.getAttributes();
+System.out.println("currentThreadCount:" + mbsc.getAttribute(threadObjName, attrName));
+```
\ No newline at end of file
diff --git a/spring3-mvc-simple/.gitignore b/spring3-mvc-simple/.gitignore
new file mode 100644
index 0000000..dcf31b9
--- /dev/null
+++ b/spring3-mvc-simple/.gitignore
@@ -0,0 +1,6 @@
+/target
+/.classpath
+/.project
+/.gradle
+/.settings
+/build
diff --git a/spring3-mvc-simple/build.gradle b/spring3-mvc-simple/build.gradle
new file mode 100644
index 0000000..164a1a7
--- /dev/null
+++ b/spring3-mvc-simple/build.gradle
@@ -0,0 +1,16 @@
+apply plugin: 'war'
+apply plugin: 'jetty'
+apply plugin: 'eclipse-wtp'
+
+repositories {
+ mavenCentral()
+}
+
+dependencies {
+ providedCompile 'javax.servlet:servlet-api:2.5'
+ compile 'org.springframework:spring-webmvc:3.2.2.RELEASE'
+ runtime 'javax.servlet:jstl:1.1.2'
+}
+
+/* Change context path (base url). otherwise defaults to name of project */
+jettyRunWar.contextPath = ''
\ No newline at end of file
diff --git a/spring3-mvc-simple/pom.xml b/spring3-mvc-simple/pom.xml
new file mode 100644
index 0000000..81a626b
--- /dev/null
+++ b/spring3-mvc-simple/pom.xml
@@ -0,0 +1,65 @@
+
+
+ 4.0.0
+
+ maven-framework-project
+ net.aimeizi
+ 1.0.0
+
+
+ net.aimeizi.springmvc.example
+ spring3-mvc-simple
+ war
+
+ spring3-mvc-simple
+ http://maven.apache.org
+
+
+
+ servlet-api
+ javax.servlet
+ 2.5
+ provided
+
+
+
+ spring-webmvc
+ org.springframework
+ 3.2.2.RELEASE
+
+
+
+ jstl
+ javax.servlet
+ 1.1.2
+
+
+
+
+ spring3-mvc-simple
+
+
+ org.eclipse.jetty
+ jetty-maven-plugin
+ 9.2.1.v20140609
+
+
+
+ org.apache.tomcat.maven
+ tomcat7-maven-plugin
+ 2.2
+
+
+
+ org.apache.tomcat.maven
+ tomcat6-maven-plugin
+ 2.2
+
+
+
+
+
+
+
+
diff --git a/spring3-mvc-simple/src/main/java/org/spring3/mvc/simple/controller/SampleController.java b/spring3-mvc-simple/src/main/java/org/spring3/mvc/simple/controller/SampleController.java
new file mode 100644
index 0000000..0aeafd3
--- /dev/null
+++ b/spring3-mvc-simple/src/main/java/org/spring3/mvc/simple/controller/SampleController.java
@@ -0,0 +1,15 @@
+package org.spring3.mvc.simple.controller;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+@Controller
+public class SampleController {
+
+ @RequestMapping("home")
+ public String loadHomePage(Model m) {
+ m.addAttribute("name", "SpringMVC");
+ return "home";
+ }
+}
diff --git a/spring3-mvc-simple/src/main/java/org/spring3/mvc/simple/springconfig/WebConfig.java b/spring3-mvc-simple/src/main/java/org/spring3/mvc/simple/springconfig/WebConfig.java
new file mode 100644
index 0000000..2aac7c6
--- /dev/null
+++ b/spring3-mvc-simple/src/main/java/org/spring3/mvc/simple/springconfig/WebConfig.java
@@ -0,0 +1,22 @@
+package org.spring3.mvc.simple.springconfig;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.view.InternalResourceViewResolver;
+
+@Configuration
+@EnableWebMvc
+@ComponentScan(basePackages = "org.spring3.mvc.simple.controller")
+public class WebConfig {
+
+ @Bean
+ public InternalResourceViewResolver viewResolver() {
+ InternalResourceViewResolver resolver = new InternalResourceViewResolver();
+ resolver.setPrefix("/WEB-INF/view/");
+ resolver.setSuffix(".jsp");
+ return resolver;
+ }
+
+}
diff --git a/spring3-mvc-simple/src/main/resources/sample-servlet.xml b/spring3-mvc-simple/src/main/resources/sample-servlet.xml
new file mode 100644
index 0000000..2f1d7a4
--- /dev/null
+++ b/spring3-mvc-simple/src/main/resources/sample-servlet.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring3-mvc-simple/src/main/webapp/WEB-INF/view/home.jsp b/spring3-mvc-simple/src/main/webapp/WEB-INF/view/home.jsp
new file mode 100644
index 0000000..21dbc67
--- /dev/null
+++ b/spring3-mvc-simple/src/main/webapp/WEB-INF/view/home.jsp
@@ -0,0 +1,9 @@
+
+
+
+ Sample Application
+
+
+ Hello, ${name}!
+
+
\ No newline at end of file
diff --git a/spring3-mvc-simple/src/main/webapp/WEB-INF/web.xml b/spring3-mvc-simple/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..ae339c0
--- /dev/null
+++ b/spring3-mvc-simple/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ sample
+
+ org.springframework.web.servlet.DispatcherServlet
+
+
+ contextClass
+ org.springframework.web.context.support.AnnotationConfigWebApplicationContext
+
+
+ contextConfigLocation
+ org.spring3.mvc.simple.springconfig
+
+
+
+
+ sample
+ /
+
+
+
\ No newline at end of file
diff --git a/spring3-mvc-simple/src/main/webapp/WEB-INF/webxml.xml b/spring3-mvc-simple/src/main/webapp/WEB-INF/webxml.xml
new file mode 100644
index 0000000..80345d1
--- /dev/null
+++ b/spring3-mvc-simple/src/main/webapp/WEB-INF/webxml.xml
@@ -0,0 +1,22 @@
+
+
+
+
+ sample
+
+ org.springframework.web.servlet.DispatcherServlet
+
+
+ contextConfigLocation
+ /WEB-INF/sample-servlet.xml
+
+
+
+
+ sample
+ /
+
+
+
\ No newline at end of file
diff --git a/spring3-rmi-example/.gitignore b/spring3-rmi-example/.gitignore
new file mode 100644
index 0000000..9dff9cc
--- /dev/null
+++ b/spring3-rmi-example/.gitignore
@@ -0,0 +1,4 @@
+/.project
+/.settings
+/target
+/.classpath
diff --git a/spring3-rmi-example/pom.xml b/spring3-rmi-example/pom.xml
new file mode 100644
index 0000000..30ea2d8
--- /dev/null
+++ b/spring3-rmi-example/pom.xml
@@ -0,0 +1,35 @@
+
+ 4.0.0
+
+ net.aimeizi
+ maven-framework-project
+ 1.0.0
+
+ spring3-rmi-example
+
+
+
+ 3.1.1.RELEASE
+
+
+
+
+ org.springframework
+ spring-core
+ ${spring.version}
+
+
+ org.springframework
+ spring-context
+ ${spring.version}
+
+
+
+ log4j
+ log4j
+ 1.2.16
+
+
+
+
\ No newline at end of file
diff --git a/spring3-rmi-example/src/main/java/net/aimeizi/rmi/cache/service/CacheService.java b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/cache/service/CacheService.java
new file mode 100644
index 0000000..93c81a3
--- /dev/null
+++ b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/cache/service/CacheService.java
@@ -0,0 +1,29 @@
+package net.aimeizi.rmi.cache.service;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+import net.aimeizi.rmi.model.User;
+
+public class CacheService implements ICacheService {
+
+ ConcurrentHashMap userMap;
+
+ /**
+ * Get User Map
+ *
+ * @return ConcurrentHashMap User Map
+ */
+ public ConcurrentHashMap getUserMap() {
+ return userMap;
+ }
+
+ /**
+ * Set User Map
+ *
+ * @param ConcurrentHashMap User Map
+ */
+ public void setUserMap(ConcurrentHashMap userMap) {
+ this.userMap = userMap;
+ }
+
+}
diff --git a/spring3-rmi-example/src/main/java/net/aimeizi/rmi/cache/service/ICacheService.java b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/cache/service/ICacheService.java
new file mode 100644
index 0000000..d5fb5fb
--- /dev/null
+++ b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/cache/service/ICacheService.java
@@ -0,0 +1,16 @@
+package net.aimeizi.rmi.cache.service;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+import net.aimeizi.rmi.model.User;
+
+public interface ICacheService {
+
+ /**
+ * Get User Map
+ *
+ * @return ConcurrentHashMap User Map
+ */
+ public ConcurrentHashMap getUserMap();
+
+}
diff --git a/spring3-rmi-example/src/main/java/net/aimeizi/rmi/client/RMIServiceClient.java b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/client/RMIServiceClient.java
new file mode 100644
index 0000000..66c0fae
--- /dev/null
+++ b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/client/RMIServiceClient.java
@@ -0,0 +1,46 @@
+package net.aimeizi.rmi.client;
+
+import net.aimeizi.rmi.model.User;
+import net.aimeizi.rmi.server.IRMIUserService;
+import net.aimeizi.rmi.server.RMIUserService;
+
+import org.apache.log4j.Logger;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class RMIServiceClient {
+
+ private static Logger logger = Logger.getLogger(RMIUserService.class);
+
+ /**
+ * Main method of the RMI Service Client
+ *
+ */
+ public static void main(String[] args) {
+
+ logger.debug("RMI Service Client is starting...");
+
+ //RMI Client Application Context is started...
+ ApplicationContext context = new ClassPathXmlApplicationContext("rmiClientAppContext.xml");
+
+ //Remote User Service is called via RMI Client Application Context...
+ IRMIUserService rmiClient = (IRMIUserService) context.getBean("RMIUserService");
+
+ //New User is created...
+ User user = new User();
+ user.setId(1);
+ user.setName("Bruce");
+ user.setSurname("Willis");
+
+ //The user is added to the remote cache...
+ rmiClient.addUser(user);
+
+ //The users are gotten via remote cache...
+ rmiClient.getUserList();
+
+ //The user is deleted from remote cache...
+ rmiClient.deleteUser(user);
+
+ logger.debug("RMI Service Client is stopped...");
+ }
+}
diff --git a/spring3-rmi-example/src/main/java/net/aimeizi/rmi/model/User.java b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/model/User.java
new file mode 100644
index 0000000..bd85314
--- /dev/null
+++ b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/model/User.java
@@ -0,0 +1,77 @@
+package net.aimeizi.rmi.model;
+
+import java.io.Serializable;
+
+@SuppressWarnings("serial")
+public class User implements Serializable {
+
+ private long id;
+ private String name;
+ private String surname;
+
+ /**
+ * Get User Id
+ *
+ * @return long id
+ */
+ public long getId() {
+ return id;
+ }
+
+ /**
+ * Set User Id
+ *
+ * @param long id
+ */
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ /**
+ * Get User Name
+ *
+ * @return long id
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Set User Name
+ *
+ * @param String
+ * name
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Get User Surname
+ *
+ * @return long id
+ */
+ public String getSurname() {
+ return surname;
+ }
+
+ /**
+ * Set User Surname
+ *
+ * @param String
+ * surname
+ */
+ public void setSurname(String surname) {
+ this.surname = surname;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder strBuilder = new StringBuilder();
+ strBuilder.append("Id : ").append(getId());
+ strBuilder.append(", Name : ").append(getName());
+ strBuilder.append(", Surname : ").append(getSurname());
+ return strBuilder.toString();
+ }
+
+}
diff --git a/spring3-rmi-example/src/main/java/net/aimeizi/rmi/server/IRMIUserService.java b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/server/IRMIUserService.java
new file mode 100644
index 0000000..5f08d02
--- /dev/null
+++ b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/server/IRMIUserService.java
@@ -0,0 +1,32 @@
+package net.aimeizi.rmi.server;
+
+import java.util.List;
+
+import net.aimeizi.rmi.model.User;
+
+public interface IRMIUserService {
+
+ /**
+ * Add User
+ *
+ * @param User user
+ * @return boolean response of the method
+ */
+ public boolean addUser(User user);
+
+ /**
+ * Delete User
+ *
+ * @param User user
+ * @return boolean response of the method
+ */
+ public boolean deleteUser(User user);
+
+ /**
+ * Get User List
+ *
+ * @return List user list
+ */
+ public List getUserList();
+
+}
diff --git a/spring3-rmi-example/src/main/java/net/aimeizi/rmi/server/RMIUserService.java b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/server/RMIUserService.java
new file mode 100644
index 0000000..6f4e01f
--- /dev/null
+++ b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/server/RMIUserService.java
@@ -0,0 +1,72 @@
+package net.aimeizi.rmi.server;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.aimeizi.rmi.cache.service.ICacheService;
+import net.aimeizi.rmi.model.User;
+
+import org.apache.log4j.Logger;
+
+public class RMIUserService implements IRMIUserService {
+
+ private static Logger logger = Logger.getLogger(RMIUserService.class);
+
+ //Remote Cache Service is injected...
+ ICacheService cacheService;
+
+ /**
+ * Add User
+ *
+ * @param User user
+ * @return boolean response of the method
+ */
+ public boolean addUser(User user) {
+ getCacheService().getUserMap().put(user.getId(), user);
+ logger.debug("User has been added to cache. User : "+getCacheService().getUserMap().get(user.getId()));
+ return true;
+ }
+
+ /**
+ * Delete User
+ *
+ * @param User user
+ * @return boolean response of the method
+ */
+ public boolean deleteUser(User user) {
+ getCacheService().getUserMap().put(user.getId(), user);
+ logger.debug("User has been deleted from cache. User : "+user);
+ return true;
+ }
+
+ /**
+ * Get User List
+ *
+ * @return List user list
+ */
+ public List getUserList() {
+ List list = new ArrayList();
+ list.addAll(getCacheService().getUserMap().values());
+ logger.debug("User List : "+list);
+ return list;
+ }
+
+ /**
+ * Get RMI User Service
+ *
+ * @return IRMIUserService RMI User Service
+ */
+ public ICacheService getCacheService() {
+ return cacheService;
+ }
+
+ /**
+ * Set RMI User Service
+ *
+ * @param IRMIUserService RMI User Service
+ */
+ public void setCacheService(ICacheService cacheService) {
+ this.cacheService = cacheService;
+ }
+
+}
diff --git a/spring3-rmi-example/src/main/java/net/aimeizi/rmi/server/starter/RMIServerStarter.java b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/server/starter/RMIServerStarter.java
new file mode 100644
index 0000000..f418991
--- /dev/null
+++ b/spring3-rmi-example/src/main/java/net/aimeizi/rmi/server/starter/RMIServerStarter.java
@@ -0,0 +1,11 @@
+package net.aimeizi.rmi.server.starter;
+
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class RMIServerStarter {
+
+ public static void main(String[] args) {
+ new ClassPathXmlApplicationContext("rmiServerAppContext.xml");
+ }
+
+}
diff --git a/spring3-rmi-example/src/main/resources/log4j.xml b/spring3-rmi-example/src/main/resources/log4j.xml
new file mode 100644
index 0000000..6d99593
--- /dev/null
+++ b/spring3-rmi-example/src/main/resources/log4j.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring3-rmi-example/src/main/resources/rmiClientAppContext.xml b/spring3-rmi-example/src/main/resources/rmiClientAppContext.xml
new file mode 100644
index 0000000..67396c8
--- /dev/null
+++ b/spring3-rmi-example/src/main/resources/rmiClientAppContext.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring3-rmi-example/src/main/resources/rmiServerAppContext.xml b/spring3-rmi-example/src/main/resources/rmiServerAppContext.xml
new file mode 100644
index 0000000..412bda9
--- /dev/null
+++ b/spring3-rmi-example/src/main/resources/rmiServerAppContext.xml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+