├── .gitignore
├── README.md
├── commons
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── com
│ │ └── tg
│ │ └── tiny4j
│ │ └── commons
│ │ ├── constants
│ │ ├── ConfigurationElement.java
│ │ ├── HttpMethod.java
│ │ └── WebApplicationEnvironment.java
│ │ ├── data
│ │ └── Pair.java
│ │ └── utils
│ │ ├── ClassUtil.java
│ │ ├── JsonUtil.java
│ │ └── Validate.java
│ └── test
│ └── com
│ └── tg
│ └── tiny4j
│ └── commons
│ └── utils
│ ├── ClassUtilTest.java
│ └── SampleBean.java
├── core
├── README.md
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── tg
│ │ │ └── tiny4j
│ │ │ └── core
│ │ │ ├── aop
│ │ │ ├── AbstractAopProxy.java
│ │ │ ├── AopProxy.java
│ │ │ ├── AutoSetterCglibAopProxy.java
│ │ │ ├── CglibAopProxy.java
│ │ │ ├── JdkDynamicAopProxy.java
│ │ │ ├── README.txt
│ │ │ ├── advice
│ │ │ │ ├── AopAdvice.java
│ │ │ │ ├── AopInterceptor.java
│ │ │ │ ├── AutoSetterCglibMethodinvocation.java
│ │ │ │ ├── BeanAnnotatedAopInterceptor.java
│ │ │ │ ├── CglibMethodinvocation.java
│ │ │ │ ├── Invocation.java
│ │ │ │ ├── JoinPointtest.java
│ │ │ │ ├── Methodinvocation.java
│ │ │ │ └── Target.java
│ │ │ └── exception
│ │ │ │ └── AdviceDefinitionException.java
│ │ │ ├── ioc
│ │ │ ├── annotation
│ │ │ │ ├── Bean.java
│ │ │ │ ├── Component.java
│ │ │ │ ├── Configuration.java
│ │ │ │ ├── Inject.java
│ │ │ │ └── Value.java
│ │ │ ├── beans
│ │ │ │ ├── BeanAnnotatedDefinition.java
│ │ │ │ ├── BeanDefinition.java
│ │ │ │ ├── BeanPostProcessor.java
│ │ │ │ ├── BeanPropertyValue.java
│ │ │ │ ├── BeanReference.java
│ │ │ │ ├── factory
│ │ │ │ │ ├── AbstractBeanFactory.java
│ │ │ │ │ ├── BeanFactory.java
│ │ │ │ │ └── DefaultBeanFactory.java
│ │ │ │ └── reader
│ │ │ │ │ ├── AbstractBeanDefinitionReader.java
│ │ │ │ │ ├── AnnotationBeanDefinitionReader.java
│ │ │ │ │ ├── AutoConfigBeanDefinitionReader.java
│ │ │ │ │ ├── BeanDefinitionReader.java
│ │ │ │ │ ├── ClassScanner.java
│ │ │ │ │ ├── PackageChecker.java
│ │ │ │ │ ├── PlaceholderPraser.java
│ │ │ │ │ └── XmlBeanDefinitionReader.java
│ │ │ ├── context
│ │ │ │ ├── AbstractApplicationContext.java
│ │ │ │ ├── ApplicationContext.java
│ │ │ │ ├── ApplicationContextHolder.java
│ │ │ │ └── ClassPathXmlApplicationContext.java
│ │ │ ├── exception
│ │ │ │ ├── BeanDefinitionException.java
│ │ │ │ ├── BeanException.java
│ │ │ │ ├── ConfigurationException.java
│ │ │ │ └── PropertyDuplicateException.java
│ │ │ └── resource
│ │ │ │ ├── Resource.java
│ │ │ │ ├── ResourceLoad.java
│ │ │ │ └── UrlResource.java
│ │ │ └── web
│ │ │ └── integration
│ │ │ ├── BootAppBeanDefinitionReader.java
│ │ │ ├── ContextListener
│ │ │ ├── AbstractBootContextListener.java
│ │ │ └── AbstractWebContextListener.java
│ │ │ ├── HandleAnnotation.java
│ │ │ ├── HandleRegistry.java
│ │ │ ├── WebAppBeanDefinitionReader.java
│ │ │ └── context
│ │ │ ├── BootApplicationContext.java
│ │ │ ├── ServletContainerApplicationContext.java
│ │ │ └── WebApplicationContext.java
│ └── resources
│ │ ├── application.properties
│ │ └── log4j2.xml
│ └── test
│ ├── java
│ └── com
│ │ └── tg
│ │ └── tiny4j
│ │ └── core
│ │ ├── aop
│ │ ├── Add.java
│ │ ├── AddOperate.java
│ │ ├── CglibDynamicAopProxyTest.java
│ │ ├── JdkDynamicAopProxyTest.java
│ │ ├── Operate.java
│ │ └── TestAopInterceptor.java
│ │ └── ioc
│ │ ├── beans
│ │ └── reader
│ │ │ ├── ConfigBean.java
│ │ │ ├── DaoBean.java
│ │ │ ├── LogBeanPostProcessor.java
│ │ │ ├── ServiceBean.java
│ │ │ └── XmlBeanDefinitionReaderTest.java
│ │ ├── context
│ │ └── ClassPathXmlApplicationContextTest.java
│ │ └── resource
│ │ └── ResourceLoadTest.java
│ └── resources
│ ├── application.properties
│ ├── log4j2.xml
│ └── test.xml
├── pom.xml
├── rest
├── README.md
├── pom.xml
└── src
│ └── main
│ └── java
│ └── com
│ └── tg
│ └── tiny4j
│ └── web
│ ├── annotation
│ ├── Api.java
│ ├── CROS.java
│ ├── ComponentScan.java
│ ├── ExceptionHandler.java
│ ├── Interceptor.java
│ ├── InterceptorExclude.java
│ ├── InterceptorInclude.java
│ ├── InterceptorSelect.java
│ ├── PathVariable.java
│ ├── RequestBody.java
│ ├── RequestMapping.java
│ └── RequestParam.java
│ ├── contextlistener
│ └── SingleRestLoaderListener.java
│ ├── exception
│ ├── ConfigurationException.java
│ ├── ExceptionHandleException.java
│ ├── InterceptorDuplicatedException.java
│ └── UrlDuplicatedException.java
│ ├── handle
│ └── RequestHandleMapping.java
│ ├── integration
│ └── WebAppControllerReader.java
│ ├── interceptor
│ └── HandlerInterceptor.java
│ ├── jettyembed
│ ├── Configuration.java
│ └── TinyApplication.java
│ ├── metadata
│ ├── BaseInfo.java
│ ├── ControllerInfo.java
│ ├── CrosInfo.java
│ ├── ExceptionHandleInfo.java
│ ├── InterceptorInfo.java
│ ├── RequestHandleInfo.java
│ ├── RequestMapper.java
│ └── UrlPraseInfo.java
│ ├── reader
│ ├── AbstractClassReader.java
│ ├── ClassScanner.java
│ ├── ConfigLoader.java
│ ├── Reader.java
│ └── WebScanedClassReader.java
│ └── servlet
│ └── DispatcherServlet.java
├── web-containerembed
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── tg
│ │ │ └── web
│ │ │ ├── Application.java
│ │ │ ├── contextlistener
│ │ │ └── BootAppLoaderListener.java
│ │ │ ├── controller
│ │ │ ├── AInterceptor.java
│ │ │ ├── BInterceptor.java
│ │ │ ├── BaseController.java
│ │ │ ├── TestController.java
│ │ │ ├── TestException.java
│ │ │ └── TestServlet.java
│ │ │ ├── dao
│ │ │ └── UserDao.java
│ │ │ ├── model
│ │ │ └── User.java
│ │ │ └── service
│ │ │ └── UserService.java
│ └── resources
│ │ ├── application.properties
│ │ └── log4j2.xml
│ └── test
│ └── java
│ └── com
│ └── tg
│ └── embed
│ ├── JetttyTest.java
│ └── TomcatTest.java
└── web-test
├── pom.xml
└── src
└── main
├── java
└── com
│ └── tg
│ └── web
│ ├── contextlistener
│ └── WebAppLoaderListener.java
│ ├── controller
│ ├── AInterceptor.java
│ ├── BInterceptor.java
│ ├── BaseController.java
│ ├── TestController.java
│ ├── TestException.java
│ └── TestServlet.java
│ ├── dao
│ └── UserDao.java
│ ├── model
│ └── User.java
│ └── service
│ └── UserService.java
├── resources
├── application.properties
├── application.xml
└── log4j2.xml
└── webapp
├── WEB-INF
└── web.xml
└── index.jsp
/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | **/target/
3 | /logs/
4 | /.settings/
5 | /.classpath
6 | /.DS_Store
7 | /.project
8 | /.idea/
9 | /*.iml
10 | *.iml
11 | /inte
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # tiny4j
2 | 会点java,做点web,基本也就是spring全家桶,都是IOC,AOP,MVC这样的概念,所以打算自己折腾一个,实现最基本最常用的一些功能。
3 | ### IOC
4 | 简单使用如下:
5 |
6 | ```
7 | ApplicationContext applicationContext = new ClassPathXmlApplicationContext("test.xml");
8 | ServiceBean serviceBean=(ServiceBean)applicationContext.getBean("testService");
9 | System.out.println(serviceBean);
10 | serviceBean.service();
11 |
12 | ServiceBean serviceBean2=(ServiceBean)applicationContext.getBean("serviceBean");
13 | System.out.println(serviceBean2);
14 | serviceBean2.service();
15 |
16 | //全局的容器上下文
17 | ApplicationContextHolder holder=applicationContext.getBean("applicationContextHolder", ApplicationContextHolder.class);
18 | System.out.println("holder get bean : "+holder.getBean("serviceBean"));
19 | ```
20 | [详细说明](https://github.com/twogoods/tiny4j/tree/master/core)
21 | ### rest
22 | 不多说直接上controller代码
23 |
24 | ```
25 | @Api("/base")
26 | public class TestController extends BaseController {
27 |
28 | @Value("${user.name:test}")
29 | private String name;
30 |
31 | @Inject
32 | private UserService userService;
33 |
34 | @RequestMapping
35 | public String index() {
36 | userService.query();
37 | return name;
38 | }
39 |
40 | @RequestMapping(mapUrl = "/test/{id}", method = HttpMethod.GET)
41 | @CROS(origins = "www.baidu.com", methods = {HttpMethod.GET}, maxAge = "3600")
42 | public String patgTest(@PathVariable("id") String id) {
43 | return id;
44 | }
45 |
46 | @RequestMapping(mapUrl = "/test", method = HttpMethod.GET)
47 | @InterceptorSelect(include = {"aInterceptor"}, exclude = {"bInterceptor"})
48 | public String interceptorTest() {
49 | return "haha";
50 | }
51 |
52 |
53 | @RequestMapping(mapUrl = "/index")
54 | @CROS
55 | public String paramTest(@RequestParam("id") long id, @RequestParam("name") String name) {
56 | return name + "---" + id;
57 | }
58 |
59 | @RequestMapping(mapUrl = "/user/{id}", method = HttpMethod.PUT)
60 | @CROS
61 | public User insert(@PathVariable("id") long id, @RequestBody User user) {
62 | return user;
63 | }
64 | }
65 | ```
66 | 是不是感觉很熟悉,SpringMvc既视感...
67 | **现已支持SpringBoot风格的可执行jar**,请看[详细说明](https://github.com/twogoods/tiny4j/tree/master/rest)
68 |
69 | TODO
70 |
71 | * 反射优化
72 |
73 | ### AOP
74 | TODO
75 |
--------------------------------------------------------------------------------
/commons/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | tiny4j
7 | com.twogoods.tiny4j
8 | 0.0.1
9 |
10 | 4.0.0
11 |
12 | commons
13 |
14 |
15 |
16 | com.alibaba
17 | fastjson
18 | 1.1.46
19 |
20 |
21 | org.apache.commons
22 | commons-io
23 | 1.3.2
24 |
25 |
26 | org.apache.commons
27 | commons-lang3
28 | 3.4
29 |
30 |
31 | commons-validator
32 | commons-validator
33 | 1.3.1
34 |
35 |
36 | commons-codec
37 | commons-codec
38 | 1.9
39 |
40 |
41 | com.google.guava
42 | guava
43 | 19.0
44 |
45 |
46 | javax.servlet
47 | javax.servlet-api
48 | 4.0.0-b03
49 |
50 |
51 | org.aspectj
52 | aspectjweaver
53 | 1.8.9
54 |
55 |
56 | cglib
57 | cglib
58 | 3.2.4
59 |
60 |
61 | com.esotericsoftware
62 | reflectasm
63 | 1.11.3
64 |
65 |
66 |
67 |
68 |
69 |
70 | org.apache.maven.plugins
71 | maven-surefire-plugin
72 |
73 | true
74 |
75 |
76 |
77 | org.apache.maven.plugins
78 | maven-compiler-plugin
79 | 3.1
80 |
81 | 1.7
82 | 1.7
83 | UTF-8
84 |
85 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/tg/tiny4j/commons/constants/ConfigurationElement.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.commons.constants;
2 |
3 | /**
4 | * Description:
5 | *
6 | * @author twogoods
7 | * @version 0.1
8 | * @since 2017-03-13
9 | */
10 | public class ConfigurationElement {
11 |
12 | public static final String COMPONENTSCAN = "tiny4j.component-scan";
13 | public static final String SERVER_CONTEXTPATH = "tiny4j.server.contextPath";
14 | public static final String SERVER_PORT = "tiny4j.server.port";
15 |
16 | public static final String DEFAULT_CONFIG_FILE = "application.properties";
17 | }
18 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/tg/tiny4j/commons/constants/HttpMethod.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.commons.constants;
2 |
3 | import org.apache.commons.lang3.StringUtils;
4 |
5 | /**
6 | * Created by twogoods on 16/11/7.
7 | */
8 | public class HttpMethod {
9 | public static final String GET = "GET";
10 | public static final String POST = "POST";
11 | public static final String PUT = "PUT";
12 | public static final String DELETE = "DELETE";
13 | //jdk7- not support
14 | public static final String PATCH = "PATCH";
15 | //cors
16 | public static final String OPTIONS = "OPTIONS";
17 | //not filter
18 | public static final String HEAD = "HEAD";
19 |
20 |
21 | public static boolean support(String httpMethod) {
22 | if(StringUtils.isEmpty(httpMethod)){
23 | return true;
24 | }
25 | return GET.equals(httpMethod) || POST.equals(httpMethod) || PUT.equals(httpMethod)
26 | || DELETE.equals(httpMethod) || PATCH.equals(httpMethod);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/tg/tiny4j/commons/constants/WebApplicationEnvironment.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.commons.constants;
2 |
3 | /**
4 | * Created by twogoods on 16/11/5.
5 | */
6 | public class WebApplicationEnvironment {
7 | public static final String RUN_MODE="run_mode";
8 | public static final String SINGLE_MODE="single";
9 | public static final String CONTAINER_MODE="container";
10 |
11 | public static final String WEBREQUESTMAPPER="webrequestmapper";
12 | public static final String ROOT_APPLICATION="root_applicationcontext";
13 |
14 |
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/tg/tiny4j/commons/data/Pair.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.commons.data;
2 |
3 | /**
4 | * Created by twogoods on 16/10/29.
5 | */
6 | public class Pair {
7 | private L l;
8 | private R r;
9 |
10 | private Pair(L l, R r) {
11 | this.l = l;
12 | this.r = r;
13 | }
14 |
15 | public static Pair of(L left, R right){
16 | return new Pair(left,right);
17 | }
18 |
19 | public L getL() {
20 | return l;
21 | }
22 |
23 | public void setL(L l) {
24 | this.l = l;
25 | }
26 |
27 | public R getR() {
28 | return r;
29 | }
30 |
31 | public void setR(R r) {
32 | this.r = r;
33 | }
34 |
35 | @Override
36 | public String toString() {
37 | return "Pair{" +
38 | "l=" + l +
39 | ", r=" + r +
40 | '}';
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/tg/tiny4j/commons/utils/ClassUtil.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.commons.utils;
2 | /**
3 | * Description:
4 | *
5 | * @author twogoods
6 | * @version 0.1
7 | * @since 2017-04-04
8 | */
9 | public class ClassUtil {
10 |
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/tg/tiny4j/commons/utils/JsonUtil.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.commons.utils;
2 | import com.alibaba.fastjson.JSON;
3 | import com.alibaba.fastjson.TypeReference;
4 | import org.apache.commons.lang3.StringUtils;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | import javax.servlet.http.HttpServletResponse;
9 | import java.io.IOException;
10 | import java.io.Writer;
11 | import java.util.Map;
12 | /**
13 | * Created by twogoods on 16/12/1.
14 | */
15 | public class JsonUtil {
16 |
17 | private static final Logger log = LoggerFactory.getLogger(JsonUtil.class);
18 |
19 | public static String jsonFromObject(Object object) {
20 | String str;
21 | try {
22 | str = JSON.toJSONString(object);
23 | } catch (RuntimeException e) {
24 | throw e;
25 | } catch (Exception e) {
26 | log.error("Unable to serialize to json: " + object, e);
27 | return null;
28 | }
29 | return str;
30 | }
31 |
32 | public static String jsonFromObject(Object object, String dateFormat) {
33 | String str;
34 | try {
35 | str = JSON.toJSONStringWithDateFormat(object, dateFormat);
36 | } catch (RuntimeException e) {
37 | throw e;
38 | } catch (Exception e) {
39 | log.error("Unable to serialize to json: " + object, e);
40 | return null;
41 | }
42 | return str;
43 | }
44 |
45 | public static T objectFromJson(String json, Class klass) {
46 | T object;
47 | try {
48 | object = JSON.parseObject(json, klass);
49 | } catch (RuntimeException e) {
50 | log.error("Runtime exception during deserializing " + klass.getSimpleName() + " from "
51 | + StringUtils.abbreviate(json, 80));
52 | throw e;
53 | } catch (Exception e) {
54 | log.error("Exception during deserializing " + klass.getSimpleName() + " from "
55 | + StringUtils.abbreviate(json, 80));
56 | return null;
57 | }
58 | return object;
59 | }
60 |
61 | public static T objectFromJson(String json, TypeReference klass) {
62 | T object;
63 | try {
64 | object = JSON.parseObject(json, klass);
65 | } catch (RuntimeException e) {
66 | log.error("Runtime exception during deserializing from " + StringUtils.abbreviate(json, 80));
67 | throw e;
68 | } catch (Exception e) {
69 | e.printStackTrace();
70 | log.error("Exception during deserializing from " + StringUtils.abbreviate(json, 80));
71 | return null;
72 | }
73 | return object;
74 | }
75 |
76 | public static Map toMap(String jsonString) {
77 | return JSON.parseObject(jsonString);
78 | }
79 |
80 | public static void writeValue(Writer writer, Object value) {
81 | JSON.writeJSONStringTo(value, writer);
82 | }
83 |
84 | public static void writeValue(HttpServletResponse response,Object value) throws IOException{
85 | response.setHeader("Content-Type", "application/json;charset=utf-8");
86 | JSON.writeJSONStringTo(value, response.getWriter());
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/tg/tiny4j/commons/utils/Validate.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.commons.utils;
2 |
3 | import java.util.List;
4 | import java.util.Set;
5 |
6 | /**
7 | * Created by twogoods on 16/10/26.
8 | */
9 | public class Validate {
10 | public static boolean isEmpty(Object obj){
11 | if(obj==null||"".equals(obj)){
12 | return true;
13 | }
14 | return false;
15 | }
16 |
17 | public static boolean isEmpty(List list){
18 | if(list==null||list.size()==0){
19 | return true;
20 | }
21 | return false;
22 | }
23 | public static boolean isEmpty(Set set){
24 | if(set==null||set.size()==0){
25 | return true;
26 | }
27 | return false;
28 | }
29 | public static boolean isEmpty(Object[] strArr){
30 | if(strArr==null||strArr.length==0){
31 | return true;
32 | }
33 | return false;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/commons/src/test/com/tg/tiny4j/commons/utils/ClassUtilTest.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.commons.utils;
2 |
3 | import com.esotericsoftware.reflectasm.MethodAccess;
4 | import net.sf.cglib.reflect.FastClass;
5 | import net.sf.cglib.reflect.FastMethod;
6 | import net.sf.cglib.reflect.MethodDelegate;
7 | import org.junit.Test;
8 |
9 | import java.lang.reflect.Method;
10 |
11 | /**
12 | * Description:
13 | *
14 | * @author twogoods
15 | * @version 0.1
16 | * @since 2017-04-04
17 | */
18 | public class ClassUtilTest {
19 | public interface BeanDelegate {
20 | String getValueFromDelegate(String s);
21 | }
22 |
23 | @Test
24 | public void testMethodDelegate() throws Exception {
25 | SampleBean bean = new SampleBean();
26 | bean.setValue("Hello cglib!");
27 | //将SampleBean的getValue方法 绑定到接口的方法
28 | BeanDelegate delegate = (BeanDelegate) MethodDelegate.create(bean, "echo", BeanDelegate.class);
29 | System.out.println(delegate.getValueFromDelegate("twogoods"));
30 | }
31 |
32 | @Test
33 | public void testFastClass() throws Exception {
34 | FastClass fastClass = FastClass.create(SampleBean.class);
35 | FastMethod fastMethod = fastClass.getMethod(SampleBean.class.getMethod("echo", String.class, int.class));
36 | SampleBean myBean = new SampleBean();
37 | myBean.setValue("Hello cglib!");
38 | long start = System.currentTimeMillis();
39 | for (int i = 0; i < 1000000; i++) {
40 | fastMethod.invoke(myBean, new Object[]{"haha" + i, 12});
41 | }
42 | System.out.println("cglib:" + (System.currentTimeMillis() - start));
43 |
44 | start = System.currentTimeMillis();
45 | Method m = SampleBean.class.getMethod("echo", String.class, int.class);
46 | for (int i = 0; i < 1000000; i++) {
47 | m.invoke(myBean, "haha" + i, 12);
48 | }
49 | System.out.println("reflect:" + (System.currentTimeMillis() - start));
50 |
51 | start = System.currentTimeMillis();
52 | for (int i = 0; i < 1000000; i++) {
53 | myBean.echo("haha" + i, 12);
54 | }
55 | System.out.println("normal:" + (System.currentTimeMillis() - start));
56 |
57 | MethodAccess access = MethodAccess.get(SampleBean.class);
58 | start = System.currentTimeMillis();
59 | for (int i = 0; i < 1000000; i++) {
60 | access.invoke(myBean, "echo", "haha" + i, 12);
61 | }
62 | System.out.println("ReflectASM:" + (System.currentTimeMillis() - start));
63 | }
64 | }
--------------------------------------------------------------------------------
/commons/src/test/com/tg/tiny4j/commons/utils/SampleBean.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.commons.utils;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Arrays;
5 | import java.util.List;
6 |
7 | /**
8 | * Description:
9 | *
10 | * @author twogoods
11 | * @version 0.1
12 | * @since 2017-04-04
13 | */
14 | public class SampleBean {
15 | private String value;
16 |
17 | public SampleBean() {
18 | }
19 |
20 | public SampleBean(String value) {
21 | this.value = value;
22 | }
23 |
24 | public String getValue() {
25 | return value;
26 | }
27 |
28 | public void setValue(String value) {
29 | this.value = value;
30 | }
31 |
32 | public String echo(String name, int age) {
33 | // List names = new ArrayList<>(100);
34 | // for (int i = 0; i < 100; i++) {
35 | // names.add(name + i);
36 | // }
37 | // List ages = new ArrayList<>(100);
38 | // for (int i = 0; i < 100; i++) {
39 | // ages.add(age + i);
40 | // }
41 | return name + "--" + age;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/core/README.md:
--------------------------------------------------------------------------------
1 | ##IOC
2 | 基于xml配置的方式
3 |
4 | ```
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | ```
19 | 编程方式使用:
20 |
21 | ```
22 | ApplicationContext applicationContext = new ClassPathXmlApplicationContext("test.xml");
23 | ServiceBean serviceBean=(ServiceBean)applicationContext.getBean("testService");
24 | System.out.println(serviceBean);
25 | serviceBean.service();
26 |
27 | ServiceBean serviceBean2=(ServiceBean)applicationContext.getBean("serviceBean");
28 | System.out.println(serviceBean2);
29 | serviceBean2.service();
30 | ```
31 | 当然你也可以添加配置文件,并配置component-scan属性来自动扫描包下的类
32 |
33 | ```
34 |
35 |
36 |
37 | application.properties
38 | ${tiny4j.component-scan:com.tg}
39 |
40 |
41 |
42 |
43 | ```
44 | 只要配置好扫描的包完全可以只使用注解
45 |
46 | ```
47 | @Configuration
48 | public class ConfigBean {
49 |
50 | @Value("${user.name:testname}")
51 | private String name;
52 | @Value("${user.pass}")
53 | private String pass;
54 |
55 | @Inject
56 | private ServiceBean serviceBean;
57 |
58 | //创建的bean的名字就是方法名
59 | @Bean
60 | public DaoBean beanAnnDao(){
61 | return new DaoBean();
62 | }
63 | @Bean
64 | public ServiceBean beanAnnService(){
65 | //new ServiceBean(beanAnnDao()); 暂不支持构造器注入
66 | ServiceBean newBean=new ServiceBean();
67 | newBean.setS1(name+"---"+serviceBean.getS1());
68 | newBean.setS2(pass+"---"+serviceBean.getS2());
69 | newBean.setDaoBean(beanAnnDao());
70 | return newBean;
71 | }
72 |
73 | }
74 | ```
75 |
76 |
--------------------------------------------------------------------------------
/core/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | tiny4j
7 | com.twogoods.tiny4j
8 | 0.0.1
9 |
10 | 4.0.0
11 |
12 | core
13 |
14 |
15 | com.twogoods.tiny4j
16 | commons
17 | 0.0.1
18 |
19 |
20 | org.aspectj
21 | aspectjweaver
22 | 1.8.9
23 |
24 |
25 | cglib
26 | cglib
27 | 3.2.4
28 |
29 |
30 |
31 |
32 |
33 |
34 | org.apache.maven.plugins
35 | maven-surefire-plugin
36 |
37 | true
38 |
39 |
40 |
41 | org.apache.maven.plugins
42 | maven-compiler-plugin
43 | 3.1
44 |
45 | 1.7
46 | 1.7
47 | UTF-8
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/aop/AbstractAopProxy.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop;
2 |
3 | import com.tg.tiny4j.core.aop.advice.AopAdvice;
4 | import com.tg.tiny4j.core.aop.exception.AdviceDefinitionException;
5 |
6 | /**
7 | * Created by twogoods on 16/10/24.
8 | */
9 | public abstract class AbstractAopProxy implements AopProxy{
10 |
11 | protected AopAdvice aopAdvice;
12 |
13 | public AbstractAopProxy(AopAdvice aopAdvice) {
14 | this.aopAdvice = aopAdvice;
15 | }
16 |
17 | public void checkAopAdvice() throws AdviceDefinitionException {
18 | if(aopAdvice.getTarget()==null){
19 | throw new AdviceDefinitionException("AopAdvice's target can't be null");
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/aop/AopProxy.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop;
2 |
3 | import com.tg.tiny4j.core.aop.exception.AdviceDefinitionException;
4 |
5 | /**
6 | * Created by twogoods on 16/10/24.
7 | */
8 | public interface AopProxy {
9 | Object getProxy() throws AdviceDefinitionException;
10 | }
11 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/aop/AutoSetterCglibAopProxy.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop;
2 |
3 | import com.tg.tiny4j.core.aop.advice.AopAdvice;
4 | import com.tg.tiny4j.core.aop.advice.AutoSetterCglibMethodinvocation;
5 | import com.tg.tiny4j.core.aop.exception.AdviceDefinitionException;
6 | import net.sf.cglib.core.Signature;
7 | import net.sf.cglib.proxy.InterfaceMaker;
8 | import net.sf.cglib.proxy.MethodProxy;
9 | import org.apache.commons.lang3.text.WordUtils;
10 | import org.objectweb.asm.Type;
11 |
12 | import java.lang.reflect.Field;
13 | import java.lang.reflect.Method;
14 | import java.util.HashMap;
15 | import java.util.Map;
16 |
17 | /**
18 | * Created by twogoods on 16/10/31.
19 | */
20 | public class AutoSetterCglibAopProxy extends CglibAopProxy{
21 |
22 | private Map autoSetter=new HashMap<>();
23 |
24 | public AutoSetterCglibAopProxy(AopAdvice aopAdvice) {
25 | super(aopAdvice);
26 | }
27 |
28 | @Override
29 | public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
30 | if (aopAdvice.getInterceptor() == null) {
31 | return methodProxy.invokeSuper(o, objects);
32 | } else {
33 | return aopAdvice.getInterceptor().invoke(new AutoSetterCglibMethodinvocation(o, method, objects, methodProxy,aopAdvice.getTarget().getClazz(),autoSetter));
34 | }
35 | }
36 |
37 | private Class createSetter() {
38 | Class objCla = aopAdvice.getTarget().getClazz();
39 | Field[] fields = objCla.getDeclaredFields();
40 | InterfaceMaker im = new InterfaceMaker();
41 | for (Field f : fields) {
42 | String setterName = "set" + WordUtils.capitalize(f.getName());
43 | try {
44 | objCla.getDeclaredMethod(setterName,f.getType());
45 | } catch (NoSuchMethodException e) {
46 | im.add(new Signature(setterName, Type.VOID_TYPE,new Type[]{Type.getType(f.getType())}), null);
47 | autoSetter.put(setterName,setterName);
48 | }
49 | }
50 | return im.create();
51 | }
52 |
53 | @Override
54 | public Object getProxy() throws AdviceDefinitionException {
55 | checkAopAdvice();
56 | enhancer.setSuperclass(aopAdvice.getTarget().getClazz());
57 | enhancer.setInterfaces(new Class[]{createSetter()});
58 | enhancer.setCallback(this);
59 | return enhancer.create();
60 | }
61 |
62 | public Map getAutoSetter() {
63 | return autoSetter;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/aop/CglibAopProxy.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop;
2 |
3 | import com.tg.tiny4j.core.aop.advice.AopAdvice;
4 | import com.tg.tiny4j.core.aop.advice.CglibMethodinvocation;
5 | import com.tg.tiny4j.core.aop.exception.AdviceDefinitionException;
6 | import net.sf.cglib.proxy.Enhancer;
7 | import net.sf.cglib.proxy.MethodInterceptor;
8 | import net.sf.cglib.proxy.MethodProxy;
9 |
10 | import java.lang.reflect.Method;
11 |
12 | /**
13 | * Created by twogoods on 16/10/24.
14 | */
15 | public class CglibAopProxy extends AbstractAopProxy implements MethodInterceptor {
16 | protected Enhancer enhancer = new Enhancer();
17 |
18 | public CglibAopProxy(AopAdvice aopAdvice) {
19 | super(aopAdvice);
20 | }
21 |
22 | @Override
23 | public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
24 | if (aopAdvice.getInterceptor() == null) {
25 | return methodProxy.invokeSuper(o, objects);
26 | } else {
27 | return aopAdvice.getInterceptor().invoke(new CglibMethodinvocation(o, method, objects, methodProxy,aopAdvice.getTarget().getClazz()));
28 | }
29 | }
30 |
31 | @Override
32 | public Object getProxy() throws AdviceDefinitionException {
33 | checkAopAdvice();
34 | enhancer.setSuperclass(aopAdvice.getTarget().getClazz());
35 | enhancer.setCallback(this);
36 | return enhancer.create();
37 | }
38 |
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/aop/JdkDynamicAopProxy.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop;
2 |
3 | import com.tg.tiny4j.commons.utils.Validate;
4 | import com.tg.tiny4j.core.aop.advice.AopAdvice;
5 | import com.tg.tiny4j.core.aop.advice.Methodinvocation;
6 | import com.tg.tiny4j.core.aop.exception.AdviceDefinitionException;
7 |
8 | import java.lang.reflect.InvocationHandler;
9 | import java.lang.reflect.Method;
10 | import java.lang.reflect.Proxy;
11 |
12 | /**
13 | * Created by twogoods on 16/10/24.
14 | */
15 | public class JdkDynamicAopProxy extends AbstractAopProxy implements InvocationHandler {
16 |
17 | public JdkDynamicAopProxy(AopAdvice aopAdvice) {
18 | super(aopAdvice);
19 | }
20 |
21 | @Override
22 | public Object getProxy() throws AdviceDefinitionException {
23 | checkAopAdvice();
24 | return Proxy.newProxyInstance(getClass().getClassLoader(), aopAdvice.getTarget().getInterfaceClazz(), this);
25 | }
26 |
27 | @Override
28 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
29 | if (aopAdvice.getInterceptor() == null) {
30 | return method.invoke(aopAdvice.getTarget().getTargetObj(), args);
31 | } else {
32 | return aopAdvice.getInterceptor().invoke(new Methodinvocation(aopAdvice.getTarget().getTargetObj(), method, args));
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/aop/README.txt:
--------------------------------------------------------------------------------
1 | 切面(Aspect): 横切关注点(跨越应用程序多个模块的功能)被模块化的特殊对象
2 | 通知(Advice): 切面必须要完成的工作
3 | 目标(Target): 被通知的对象
4 | 代理(Proxy): 向目标对象应用通知之后创建的对象
5 | 连接点(Joinpoint):程序执行的某个特定位置:如类某个方法调用前、调用后、方法抛出异常后等。
6 | 连接点由两个信息确定:方法表示的程序执行点;相对点表示的方位。例如 ArithmethicCalculator#add() 方法执行前的连接点,
7 | 执行点为 ArithmethicCalculator#add(); 方位为该方法执行前的位置
8 | 切点(pointcut):每个类都拥有多个连接点.AOP 通过切点定位到特定的连接点。类比:连接点相当于数据库中的记录,切点相当于查询条件。
9 | 切点和连接点不是一对一的关系,一个切点匹配多个连接点.
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/aop/advice/AopAdvice.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop.advice;
2 |
3 | /**
4 | * Created by twogoods on 16/10/25.
5 | */
6 | public class AopAdvice {
7 | private Target target;
8 | private AopInterceptor interceptor;
9 |
10 | public Target getTarget() {
11 | return target;
12 | }
13 |
14 | public void setTarget(Target target) {
15 | this.target = target;
16 | }
17 |
18 | public AopInterceptor getInterceptor() {
19 | return interceptor;
20 | }
21 |
22 | public void setInterceptor(AopInterceptor interceptor) {
23 | this.interceptor = interceptor;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/aop/advice/AopInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop.advice;
2 |
3 | /**
4 | * Created by twogoods on 16/10/24.
5 | */
6 | public interface AopInterceptor {
7 |
8 | Object invoke(Methodinvocation invocation) throws Throwable;
9 |
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/aop/advice/AutoSetterCglibMethodinvocation.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop.advice;
2 |
3 | import net.sf.cglib.proxy.MethodProxy;
4 |
5 | import java.lang.reflect.Method;
6 | import java.util.Map;
7 |
8 | /**
9 | * Created by twogoods on 16/10/31.
10 | */
11 | public class AutoSetterCglibMethodinvocation extends CglibMethodinvocation {
12 | private Map autoSetter;
13 |
14 | public AutoSetterCglibMethodinvocation(Object target, Method method, Object[] args, MethodProxy methodProxy, Map autoSetter) {
15 | super(target, method, args, methodProxy);
16 | this.autoSetter = autoSetter;
17 | }
18 |
19 | public AutoSetterCglibMethodinvocation(Object target, Method method, Object[] args, MethodProxy methodProxy, Class clazz, Map autoSetter) {
20 | super(target, method, args, methodProxy, clazz);
21 | this.autoSetter = autoSetter;
22 | }
23 |
24 | public Map getAutoSetter() {
25 | return autoSetter;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/aop/advice/BeanAnnotatedAopInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop.advice;
2 |
3 | import com.tg.tiny4j.commons.utils.Validate;
4 | import com.tg.tiny4j.core.ioc.beans.BeanDefinition;
5 | import com.tg.tiny4j.core.ioc.beans.factory.BeanFactory;
6 | import org.apache.commons.lang3.text.WordUtils;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | import java.lang.reflect.Field;
11 | import java.util.Map;
12 |
13 | /**
14 | * Created by twogoods on 16/10/30.
15 | */
16 |
17 | public class BeanAnnotatedAopInterceptor implements AopInterceptor {
18 | private static final Logger log = LoggerFactory.getLogger(BeanAnnotatedAopInterceptor.class);
19 |
20 | private Map methodsMap;
21 |
22 | Map beans;
23 |
24 | private BeanFactory beanFactory;
25 |
26 |
27 | public BeanAnnotatedAopInterceptor(Map methodInfos, BeanFactory beanFactory) {
28 | this.methodsMap = methodInfos;
29 | this.beanFactory = beanFactory;
30 | }
31 |
32 | public BeanAnnotatedAopInterceptor(Map methodsMap, Map beans, BeanFactory beanFactory) {
33 | this.methodsMap = methodsMap;
34 | this.beans = beans;
35 | this.beanFactory = beanFactory;
36 | }
37 |
38 | public BeanAnnotatedAopInterceptor(Map methodsMap, Map beans) {
39 | this.methodsMap = methodsMap;
40 | this.beans = beans;
41 | }
42 |
43 | @Override
44 | public Object invoke(Methodinvocation invocation) throws Throwable {
45 | String methodName = invocation.getMethod().getName();
46 | if (invocation instanceof AutoSetterCglibMethodinvocation) {
47 | Map autoSetter = ((AutoSetterCglibMethodinvocation) invocation).getAutoSetter();
48 | if (!Validate.isEmpty(autoSetter.get(methodName))) {
49 | log.debug("do setter method:{} ", methodName);
50 | Field f = invocation.getObjClass().getDeclaredField(getFieldNameBySetter(methodName));
51 | f.setAccessible(true);
52 | f.set(invocation.getTarget(), invocation.getArguments()[0]);
53 | return null;
54 | }
55 | }
56 | if (methodsMap.containsKey(methodName)) {
57 | log.debug("interceptor the @Bean method:{}", methodName);
58 | Object bean = beans.get(methodsMap.get(methodName)).getBean();
59 | if (bean == null) {
60 | //这里是调用用户方法创建的一个对象,放回容器
61 | Object obj = invocation.proceed();
62 | beans.get(methodsMap.get(methodName)).setBean(obj);
63 | return obj;
64 | }
65 | return bean;
66 | }
67 | return invocation.proceed();
68 | }
69 |
70 | private String getFieldNameBySetter(String setterName) {
71 | return WordUtils.uncapitalize(setterName.substring("set".length()));
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/aop/advice/CglibMethodinvocation.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop.advice;
2 |
3 | import net.sf.cglib.proxy.MethodProxy;
4 |
5 | import java.lang.reflect.Method;
6 |
7 | /**
8 | * Created by twogoods on 16/10/25.
9 | */
10 | public class CglibMethodinvocation extends Methodinvocation{
11 | private MethodProxy methodProxy;
12 | private Class clazz;
13 |
14 | public CglibMethodinvocation(Object target, Method method, Object[] args,MethodProxy methodProxy) {
15 | super(target, method, args);
16 | this.methodProxy=methodProxy;
17 | }
18 |
19 | public CglibMethodinvocation(Object target, Method method, Object[] args, MethodProxy methodProxy, Class clazz) {
20 | super(target, method, args,clazz);
21 | this.methodProxy = methodProxy;
22 | }
23 |
24 | @Override
25 | public Object proceed() throws Throwable {
26 | return methodProxy.invokeSuper(target,args);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/aop/advice/Invocation.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop.advice;
2 |
3 | import java.lang.reflect.Method;
4 |
5 |
6 | /**
7 | * Created by twogoods on 16/10/24.
8 | */
9 | interface Invocation {
10 | Object proceed() throws Throwable;
11 |
12 | Object getTarget();
13 |
14 | Object[] getArguments();
15 |
16 | Method getMethod();
17 |
18 | Class getObjClass();
19 |
20 | }
21 |
22 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/aop/advice/JoinPointtest.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop.advice;
2 |
3 | import java.lang.reflect.Method;
4 |
5 | /**
6 | * Created by twogoods on 16/10/24.
7 | */
8 | public class JoinPointtest implements Invocation{
9 | private Object target;
10 | private Method method;
11 | private Object[] args;
12 | private Class objClass;
13 |
14 | public JoinPointtest(Object target, Method method, Object[] args) {
15 | this.target = target;
16 | this.method = method;
17 | this.args = args;
18 | }
19 |
20 | @Override
21 | public Object proceed() throws Throwable{
22 | return method.invoke(target,args);
23 | }
24 |
25 | @Override
26 | public Object getTarget() {
27 | return target;
28 | }
29 |
30 | @Override
31 | public Object[] getArguments() {
32 | return args;
33 | }
34 |
35 | @Override
36 | public Method getMethod() {
37 | return method;
38 | }
39 |
40 | @Override
41 | public Class getObjClass() {
42 | return objClass;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/aop/advice/Methodinvocation.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop.advice;
2 |
3 |
4 | import java.lang.reflect.Method;
5 |
6 | /**
7 | * Created by twogoods on 16/10/24.
8 | */
9 | public class Methodinvocation implements Invocation {
10 |
11 | protected Object target;
12 | protected Method method;
13 | protected Object[] args;
14 | protected Class objClass;
15 |
16 | public Methodinvocation(Object target, Method method, Object[] args) {
17 | this.target = target;
18 | this.method = method;
19 | this.args = args;
20 | }
21 |
22 | public Methodinvocation(Object target, Method method, Object[] args, Class objClass) {
23 | this.target = target;
24 | this.method = method;
25 | this.args = args;
26 | this.objClass = objClass;
27 | }
28 |
29 | @Override
30 | public Object proceed() throws Throwable {
31 | return method.invoke(target, args);
32 | }
33 |
34 | @Override
35 | public Object getTarget() {
36 | return target;
37 | }
38 |
39 | @Override
40 | public Object[] getArguments() {
41 | return args;
42 | }
43 |
44 | @Override
45 | public Method getMethod() {
46 | return method;
47 | }
48 |
49 | @Override
50 | public Class getObjClass() {
51 | return objClass;
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/aop/advice/Target.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop.advice;
2 |
3 | /**
4 | * Created by twogoods on 16/10/25.
5 | */
6 | public class Target {
7 | private Object targetObj;
8 | private Class> clazz;
9 | private Class>[] interfaceClazz;
10 |
11 | public Target(Object target, Class> clazz, Class>[] interfaceClazz) {
12 | this.targetObj = target;
13 | this.clazz = clazz;
14 | this.interfaceClazz = interfaceClazz;
15 | }
16 |
17 | public Target(Class> clazz) {
18 | this.clazz = clazz;
19 | }
20 |
21 | public Object getTargetObj() {
22 | return targetObj;
23 | }
24 |
25 | public void setTargetObj(Object targetObj) {
26 | this.targetObj = targetObj;
27 | }
28 |
29 | public Class> getClazz() {
30 | return clazz;
31 | }
32 |
33 | public void setClazz(Class> clazz) {
34 | this.clazz = clazz;
35 | }
36 |
37 | public Class>[] getInterfaceClazz() {
38 | return interfaceClazz;
39 | }
40 |
41 | public void setInterfaceClazz(Class>[] interfaceClazz) {
42 | this.interfaceClazz = interfaceClazz;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/aop/exception/AdviceDefinitionException.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop.exception;
2 |
3 | /**
4 | * Created by twogoods on 16/10/25.
5 | */
6 | public class AdviceDefinitionException extends Exception {
7 | public AdviceDefinitionException(String message) {
8 | super(message);
9 | }
10 |
11 | public AdviceDefinitionException(String message, Throwable cause) {
12 | super(message, cause);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/annotation/Bean.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Created by twogoods on 16/10/27.
10 | */
11 | @Target({ElementType.METHOD})
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface Bean {
14 | String name() default "";
15 | }
16 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/annotation/Component.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Created by twogoods on 16/10/27.
10 | */
11 | @Target({ElementType.TYPE,ElementType.ANNOTATION_TYPE})
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface Component {
14 | String name() default "";
15 | }
16 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/annotation/Configuration.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Created by twogoods on 16/10/27.
10 | */
11 | @Target({ElementType.TYPE})
12 | @Retention(RetentionPolicy.RUNTIME)
13 | @Component
14 | public @interface Configuration {
15 | String name()default "";
16 | }
17 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/annotation/Inject.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Created by twogoods on 16/10/27.
10 | */
11 | @Target({ElementType.FIELD})
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface Inject {
14 | String name() default "";
15 | }
16 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/annotation/Value.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Created by twogoods on 16/10/27.
10 | */
11 | @Target({ElementType.FIELD})
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface Value {
14 | String value();
15 | }
16 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/beans/BeanAnnotatedDefinition.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans;
2 |
3 | import com.tg.tiny4j.core.aop.advice.AopAdvice;
4 | import com.tg.tiny4j.core.aop.advice.AopInterceptor;
5 | import com.tg.tiny4j.core.aop.advice.Methodinvocation;
6 |
7 | import java.util.HashMap;
8 | import java.util.List;
9 | import java.util.Map;
10 |
11 | /**
12 | * Created by twogoods on 16/10/30.
13 | */
14 | public class BeanAnnotatedDefinition extends BeanDefinition{
15 | public BeanAnnotatedDefinition(String id, String classname) throws ClassNotFoundException {
16 | super(id, classname);
17 | }
18 |
19 | public BeanAnnotatedDefinition(String id, Class clazz) {
20 | super(id, clazz);
21 | }
22 |
23 | private Map methodInfos=new HashMap<>();
24 |
25 | private AopAdvice aopAdvice;
26 |
27 | public void putmethodInfo(String methodName,String beanName) {
28 | methodInfos.put(methodName,beanName);
29 | }
30 | public void putmethodInfos(Map infos) {
31 | methodInfos.putAll(infos);
32 | }
33 |
34 | public Map getMethodInfos() {
35 | return methodInfos;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/beans/BeanDefinition.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans;
2 |
3 | import com.tg.tiny4j.core.ioc.exception.PropertyDuplicateException;
4 |
5 | import java.util.HashSet;
6 | import java.util.Set;
7 |
8 | /**
9 | * Created by twogoods on 16/10/26.
10 | */
11 | public class BeanDefinition {
12 | private Object bean;
13 | private String id;
14 | private String classname;
15 | private Class clazz;
16 | private Set properties=new HashSet();
17 |
18 | public BeanDefinition() {}
19 |
20 | public BeanDefinition(String id, String classname) throws ClassNotFoundException {
21 | this.id = id;
22 | this.classname = classname;
23 | clazz=Class.forName(classname);
24 | }
25 |
26 | public BeanDefinition(String id, String classname, Class clazz) {
27 | this.id = id;
28 | this.classname = classname;
29 | this.clazz = clazz;
30 | }
31 |
32 | public BeanDefinition(String id, Class clazz) {
33 | this.id = id;
34 | this.clazz = clazz;
35 | this.classname=clazz.getCanonicalName();
36 | }
37 |
38 | public void addProperty(BeanPropertyValue beanProperty) throws PropertyDuplicateException {
39 | if (properties.contains(beanProperty)) {
40 | throw new PropertyDuplicateException(String.format("class:%s , property '%s' is duplicate",classname,beanProperty.getName()));
41 | }
42 | properties.add(beanProperty);
43 | }
44 |
45 | public Set getProperties() {
46 | return properties;
47 | }
48 |
49 | public String getId() {
50 | return id;
51 | }
52 |
53 | public String getClassname() {
54 | return classname;
55 | }
56 |
57 | public Object getBean() {
58 | return bean;
59 | }
60 |
61 | public void setBean(Object bean) {
62 | this.bean = bean;
63 | }
64 |
65 | public Class getClazz() {
66 | return clazz;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/beans/BeanPostProcessor.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans;
2 |
3 | /**
4 | * Created by twogoods on 16/10/26.
5 | */
6 | public interface BeanPostProcessor {
7 | Object postProcessBeforeInitialization(Object bean, String beanName);
8 |
9 | Object postProcessAfterInitialization(Object bean, String beanName);
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/beans/BeanPropertyValue.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans;
2 |
3 | import java.util.Objects;
4 |
5 | /**
6 | * Created by twogoods on 16/10/26.
7 | */
8 | public class BeanPropertyValue {
9 | private String name;
10 | private Object value;
11 |
12 | public BeanPropertyValue() {
13 | }
14 |
15 | public BeanPropertyValue(String name, Object value) {
16 | this.name = name;
17 | this.value = value;
18 | }
19 |
20 | public String getName() {
21 | return name;
22 | }
23 |
24 | public void setName(String name) {
25 | this.name = name;
26 | }
27 |
28 | public Object getValue() {
29 | return value;
30 | }
31 |
32 | public void setValue(Object value) {
33 | this.value = value;
34 | }
35 |
36 | public boolean equals(Object o) {
37 | if (this == o) return true;
38 | if (o == null || getClass() != o.getClass()) return false;
39 | BeanPropertyValue that = (BeanPropertyValue) o;
40 | return Objects.equals(name, that.name);
41 | }
42 |
43 | @Override
44 | public int hashCode() {
45 | return Objects.hash(name);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/beans/BeanReference.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans;
2 |
3 | /**
4 | * Created by twogoods on 16/10/26.
5 | */
6 | public class BeanReference {
7 | private String name;
8 | private Object bean;
9 |
10 | public BeanReference() {
11 | }
12 |
13 | public BeanReference(String ref) {
14 | this.name = ref;
15 | }
16 |
17 | public String getName() {
18 | return name;
19 | }
20 |
21 | public void setName(String name) {
22 | this.name = name;
23 | }
24 |
25 | public Object getBean() {
26 | return bean;
27 | }
28 |
29 | public void setBean(Object bean) {
30 | this.bean = bean;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/beans/factory/AbstractBeanFactory.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans.factory;
2 |
3 | import com.tg.tiny4j.commons.utils.Validate;
4 | import com.tg.tiny4j.core.aop.AopProxy;
5 | import com.tg.tiny4j.core.aop.AutoSetterCglibAopProxy;
6 | import com.tg.tiny4j.core.aop.advice.AopAdvice;
7 | import com.tg.tiny4j.core.aop.advice.BeanAnnotatedAopInterceptor;
8 | import com.tg.tiny4j.core.aop.advice.Target;
9 | import com.tg.tiny4j.core.ioc.beans.*;
10 | import com.tg.tiny4j.core.ioc.exception.BeanException;
11 | import org.apache.commons.lang3.text.WordUtils;
12 | import org.slf4j.Logger;
13 | import org.slf4j.LoggerFactory;
14 |
15 | import java.lang.reflect.Field;
16 | import java.lang.reflect.Method;
17 | import java.util.*;
18 |
19 | /**
20 | * Created by twogoods on 16/10/25.
21 | */
22 | public abstract class AbstractBeanFactory implements BeanFactory {
23 |
24 | private static Logger log = LoggerFactory.getLogger(AbstractBeanFactory.class);
25 |
26 | private Map beans = new HashMap<>();
27 |
28 | private List postProcessorList = new ArrayList<>();
29 |
30 | private void selectBeanPostProcessor() throws Exception {
31 | if (postProcessorList.size() == 0) {
32 | log.debug("beans :{}", beans);
33 | for (String beanName : beans.keySet()) {
34 | String classname = beans.get(beanName).getClassname();
35 | if (BeanPostProcessor.class.isAssignableFrom(Class.forName(classname))) {
36 | postProcessorList.add((BeanPostProcessor) getBean(beanName));
37 | }
38 | }
39 | }
40 | }
41 |
42 | public void preInstantiateSingletons() throws Exception {
43 | selectBeanPostProcessor();
44 | for (Iterator it = beans.keySet().iterator(); it.hasNext(); ) {
45 | String beanName = (String) it.next();
46 | getBean(beanName);
47 | }
48 | }
49 |
50 | private Object createBeanAnnotatedBean(BeanAnnotatedDefinition beanAnnotatedDefinition) throws Exception {
51 | /**
52 | * 1.创建一个普通对象,把属性都赋好值
53 | * 2.设置aopadvice
54 | * 3.创建cglib代理对象
55 | * 4.为这个代理对象附上1中得到对象的属性值
56 | * 5.调用这个代理对象的方法,aop的拦截器里会调真正的那个方法,创建第一个对象出来,这个时候把这个对象放到容器里
57 | */
58 | Object obj = createBean(beanAnnotatedDefinition);
59 |
60 | AopAdvice beanAnnotatedAopAdvice = new AopAdvice();
61 | beanAnnotatedAopAdvice.setTarget(new Target(beanAnnotatedDefinition.getClazz()));
62 | beanAnnotatedAopAdvice.setInterceptor(new BeanAnnotatedAopInterceptor(beanAnnotatedDefinition.getMethodInfos(),beans, this));
63 |
64 | AopProxy aopProxy = new AutoSetterCglibAopProxy(beanAnnotatedAopAdvice);
65 | Object proxyObj = aopProxy.getProxy();
66 |
67 | Class proxyClass = proxyObj.getClass();
68 | Field[] fields = obj.getClass().getDeclaredFields();
69 | for (Field f : fields) {
70 | try {
71 | f.setAccessible(true);
72 | Method setter = proxyClass.getDeclaredMethod(getSetterName(f.getName()), f.getType());
73 | setter.invoke(proxyObj, f.get(obj));
74 | } catch (NoSuchMethodException e) {
75 | log.warn(e.getMessage());
76 | }
77 | }
78 | Map annotatedMethods = beanAnnotatedDefinition.getMethodInfos();
79 | log.debug("bean have @Bean method:{}",annotatedMethods);
80 | for (String methodName : annotatedMethods.keySet()) {
81 | proxyClass.getDeclaredMethod(methodName).invoke(proxyObj);
82 | }
83 | return proxyObj;
84 | }
85 |
86 | private String getSetterName(String fieldName) {
87 | return "set" + WordUtils.capitalize(fieldName);
88 | }
89 |
90 | @Override
91 | public Object getBean(String name) throws Exception {
92 | BeanDefinition beanDefinition = beans.get(name);
93 | if (Validate.isEmpty(beanDefinition)) {
94 | throw new BeanException(String.format("no bean named %s is define", name));
95 | }
96 | Object bean = beanDefinition.getBean();
97 | if (Validate.isEmpty(bean)) {
98 | if (beanDefinition instanceof BeanAnnotatedDefinition) {
99 | bean= createBeanAnnotatedBean((BeanAnnotatedDefinition) beanDefinition);
100 | bean = postProcess(bean, name);
101 | beanDefinition.setBean(bean);
102 | } else {
103 | bean = createBean(beans.get(name));
104 | bean = postProcess(bean, name);
105 | beanDefinition.setBean(bean);
106 | }
107 | }
108 | return bean;
109 | }
110 |
111 | private Object postProcess(Object bean, String name) {
112 | for (BeanPostProcessor postProcessor : postProcessorList) {
113 | bean = postProcessor.postProcessBeforeInitialization(bean, name);
114 | }
115 | //spring 的bean配置里有一个initmetod,会在这里执行,此处略过
116 | for (BeanPostProcessor postProcessor : postProcessorList) {
117 | bean = postProcessor.postProcessAfterInitialization(bean, name);
118 | }
119 | return bean;
120 | }
121 |
122 | private Object createBean(BeanDefinition beanDefinition) throws Exception {
123 | //TODO 不支持构造函数设置属性值
124 | Object o = beanDefinition.getClazz().newInstance();
125 | applyValue(o, beanDefinition);
126 | return o;
127 | }
128 |
129 | private void applyValue(Object bean, BeanDefinition beanDefinition) throws Exception {
130 | Set properties = beanDefinition.getProperties();
131 | Iterator iterator = properties.iterator();
132 | while (iterator.hasNext()) {
133 | BeanPropertyValue propertyValue = iterator.next();
134 | String propertyName = propertyValue.getName();
135 | Object value = propertyValue.getValue();
136 | if (value instanceof BeanReference) {
137 | BeanReference beanReference = (BeanReference) value;
138 | value = getBean(beanReference.getName());
139 | }
140 | try {
141 | /*
142 | TODO 类型转化,现在只能string
143 | Field declaredField = bean.getClass().getDeclaredField(propertyValue.getName());
144 | // int 为 Interger.type
145 | Class type=declaredField.getType();
146 | declaredField.setAccessible(true);
147 | declaredField.set(bean, value);
148 | */
149 |
150 | Field declaredField = bean.getClass().getDeclaredField(propertyValue.getName());
151 | declaredField.setAccessible(true);
152 | declaredField.set(bean, value);
153 | } catch (NoSuchFieldException e) {
154 | Method declaredMethod = bean.getClass().getDeclaredMethod(
155 | "set" + WordUtils.capitalize(propertyValue.getName()), value.getClass());
156 | declaredMethod.setAccessible(true);
157 | }
158 | }
159 |
160 | }
161 |
162 | public void addPostProcessorList(BeanPostProcessor beanPostProcessor) {
163 | postProcessorList.add(beanPostProcessor);
164 | }
165 |
166 | public void addBeanDefinition(String name, BeanDefinition beanDefinition) {
167 | beans.put(name, beanDefinition);
168 | }
169 |
170 | public void addBeanDefinition(Map beanDefinitionMap) {
171 | beans.putAll(beanDefinitionMap);
172 | }
173 |
174 | @Override
175 | public T getBean(String name, Class clazz) throws Exception {
176 | Object bean = getBean(name);
177 | if (bean.getClass().equals(clazz)) {
178 | return (T) bean;
179 | }
180 | log.warn("bean:{},type:{} can not find", name, clazz);
181 | return null;
182 | }
183 |
184 | @Override
185 | public boolean containsBean(String name) throws Exception {
186 | return !Validate.isEmpty(getBean(name));
187 | }
188 |
189 |
190 | }
191 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/beans/factory/BeanFactory.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans.factory;
2 |
3 | /**
4 | * Created by twogoods on 16/10/25.
5 | */
6 | public interface BeanFactory {
7 | Object getBean(String name) throws Exception;
8 |
9 | T getBean(String name, Class clazz) throws Exception;
10 |
11 | boolean containsBean(String name) throws Exception;
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/beans/factory/DefaultBeanFactory.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans.factory;
2 |
3 | /**
4 | * Created by twogoods on 16/10/25.
5 | */
6 | public class DefaultBeanFactory extends AbstractBeanFactory{
7 |
8 | public DefaultBeanFactory() {}
9 | }
10 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/beans/reader/AbstractBeanDefinitionReader.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans.reader;
2 |
3 | import com.tg.tiny4j.core.ioc.beans.BeanDefinition;
4 | import com.tg.tiny4j.core.ioc.exception.ConfigurationException;
5 | import com.tg.tiny4j.core.ioc.resource.ResourceLoad;
6 | import org.apache.commons.lang3.StringUtils;
7 | import org.apache.commons.lang3.text.WordUtils;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | import java.util.*;
12 |
13 | /**
14 | * Created by twogoods on 16/10/26.
15 | */
16 | public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader {
17 | private static final Logger log = LoggerFactory.getLogger(AbstractBeanDefinitionReader.class);
18 |
19 | private Map registerBeans;
20 |
21 | private Map configMap;
22 |
23 | public AbstractBeanDefinitionReader() {
24 | registerBeans = new HashMap<>();
25 | configMap = new HashMap<>();
26 | }
27 |
28 | public void loadConfig(String filePath) throws Exception {
29 | Properties prop = null;
30 | try {
31 | prop = ResourceLoad.getInstance().loadConfig(filePath);
32 | Enumeration en = prop.propertyNames();
33 | while (en.hasMoreElements()) {
34 | String strKey = (String) en.nextElement();
35 | configMap.put(strKey, prop.getProperty(strKey));
36 | log.debug("get config : {} = {}", strKey, prop.getProperty(strKey));
37 | }
38 | } catch (ConfigurationException e) {
39 | log.warn(e.getMessage());
40 | } catch (Exception e1) {
41 | throw e1;
42 | }
43 | }
44 |
45 | @Override
46 | public Map getRegisterBeans() {
47 | return registerBeans;
48 | }
49 |
50 |
51 | protected String getConfigValue(PlaceholderPraser.KeyAndDefault valueAndDefault) {
52 | String value = configMap.get(valueAndDefault.getName());
53 | if (value == null) {
54 | return valueAndDefault.getDefaultValue();
55 | }
56 | return value;
57 | }
58 |
59 | protected String getConfigValue(String element) {
60 | return configMap.get(element);
61 | }
62 |
63 | /**
64 | * 通过全类名得到bean名
65 | *
66 | * @param classname
67 | * @return
68 | */
69 | protected static String getBeanNameByClassName(String classname) {
70 | String[] path = classname.split("\\.");
71 | return WordUtils.uncapitalize(path[path.length - 1]);
72 | }
73 |
74 | /**
75 | * 未写注解参数,类名首字母小写
76 | */
77 | protected String getBeanName(String annotName, Class clazz) {
78 | if (StringUtils.isEmpty(annotName)) {
79 | return WordUtils.uncapitalize(clazz.getSimpleName());
80 | }
81 | return annotName;
82 | }
83 |
84 | protected String getBeanName(String annotName, String defaultName) {
85 | if (StringUtils.isEmpty(annotName)) {
86 | return WordUtils.uncapitalize(defaultName);
87 | }
88 | return annotName;
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/beans/reader/AnnotationBeanDefinitionReader.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans.reader;
2 |
3 | import com.tg.tiny4j.core.ioc.beans.BeanAnnotatedDefinition;
4 | import com.tg.tiny4j.core.ioc.beans.BeanDefinition;
5 | import com.tg.tiny4j.core.ioc.beans.BeanPropertyValue;
6 | import com.tg.tiny4j.core.ioc.beans.BeanReference;
7 | import com.tg.tiny4j.core.ioc.exception.BeanDefinitionException;
8 | import com.tg.tiny4j.core.ioc.annotation.*;
9 | import com.tg.tiny4j.commons.data.Pair;
10 | import org.slf4j.Logger;
11 | import org.slf4j.LoggerFactory;
12 |
13 | import java.lang.annotation.Annotation;
14 | import java.lang.reflect.Field;
15 | import java.lang.reflect.Method;
16 | import java.util.*;
17 |
18 | /**
19 | * Created by twogoods on 16/10/26.
20 | */
21 | public abstract class AnnotationBeanDefinitionReader extends AbstractBeanDefinitionReader {
22 | private static Logger log = LoggerFactory.getLogger(AnnotationBeanDefinitionReader.class);
23 |
24 | private List scanPackages = new ArrayList<>();
25 |
26 | private Set classSet = new HashSet<>();
27 |
28 | public AnnotationBeanDefinitionReader() {
29 | }
30 |
31 | public AnnotationBeanDefinitionReader(List scanPackages) {
32 | this.scanPackages = scanPackages;
33 | }
34 |
35 | @Override
36 | public void loadResource() throws Exception {
37 | Set classes = ClassScanner.getClasses(scanPackages);
38 | loadClasses(classes);
39 | praseAutoConfigurationClass();
40 | }
41 |
42 | private void loadClasses(Set classes) throws ClassNotFoundException {
43 | for (String className : classes) {
44 | classSet.add(Class.forName(className));
45 | }
46 | }
47 |
48 | private void praseAutoConfigurationClass() throws Exception {
49 | for (Class clazz : classSet) {
50 | Pair result = checkBeanAnnotated(clazz);
51 | if (result.getL() && result.getR()) {
52 | praseBeanAnnotatedClass(clazz);
53 | } else if (result.getL()) {
54 | praseClass(clazz);
55 | } else {
56 | //别的注解
57 | praseUnknowAnnotatedClass(clazz);
58 | }
59 | }
60 | }
61 |
62 | /**
63 | * pair的left指明是否是配置的bean,right指是否有@Bean注解
64 | */
65 | private Pair checkBeanAnnotated(Class clazz) {
66 | if (clazz.isAnnotationPresent(Configuration.class) || clazz.isAnnotationPresent(Component.class)) {
67 | Method[] methods = clazz.getDeclaredMethods();
68 | for (Method method : methods) {
69 | if (method.isAnnotationPresent(Bean.class)) {
70 | return Pair.of(true, true);
71 | }
72 | }
73 | return Pair.of(true, false);
74 | }
75 | return Pair.of(false, false);
76 | }
77 |
78 | private void praseBeanAnnotatedClass(Class clazz) throws Exception {
79 | BeanDefinition beanDefinition = handleTypeAnnot(clazz, true);
80 | if (beanDefinition == null) {
81 | return;
82 | }
83 | handleFieldAnnot(clazz, beanDefinition);
84 | //多一个步骤解析方法
85 | Map methodinfos = handleMethodAnnotAndRegister(clazz);
86 | ((BeanAnnotatedDefinition) beanDefinition).putmethodInfos(methodinfos);
87 | registerBean(beanDefinition);
88 | }
89 |
90 | private void praseClass(Class clazz) throws Exception {
91 | BeanDefinition beanDefinition = handleTypeAnnot(clazz, false);
92 | if (beanDefinition == null) {
93 | return;
94 | }
95 | handleFieldAnnot(clazz, beanDefinition);
96 | registerBean(beanDefinition);
97 | }
98 |
99 | private void praseUnknowAnnotatedClass(Class clazz) throws Exception {
100 | BeanDefinition beanDefinition = handleIntegrationAnnotation(clazz);
101 | if (beanDefinition == null) {
102 | return;
103 | }
104 | handleFieldAnnot(clazz, beanDefinition);
105 | registerBean(beanDefinition);
106 | }
107 |
108 | public abstract BeanDefinition handleIntegrationAnnotation(Class clazz) throws Exception;
109 |
110 | /**
111 | * TODO 重构,annotation去重,去掉多余的 @Component
112 | * 目前只有@Component一个注解是ElementType.ANNOTATION_TYPE的,且只有@Component和@Configuration可以注解类
113 | * 那么只针对当前model下定义的这些注解做特殊情况处理
114 | * 后续重构,支持任一的注解检查
115 | */
116 | private Annotation[] deDuplicationAnnotation(Annotation[] annotations) {
117 | List componentIndex = new ArrayList<>(annotations.length);
118 | boolean flag = false;
119 | for (int i = 0; i < annotations.length; i++) {
120 | //有没有Component注解
121 | if (annotations[i].annotationType() == Component.class) {
122 | componentIndex.add(i);
123 | } else {
124 | //有没有被Component注解的注解
125 | if (isAnnotated(annotations[i].annotationType(), Component.class)) {
126 | flag = true;
127 | }
128 | }
129 | }
130 | if (flag && componentIndex.size() > 0) {
131 | //去掉多余的Component注解
132 | Annotation[] result = new Annotation[annotations.length - componentIndex.size()];
133 | for (int i = 0, j = 0, index = 0; i < annotations.length; i++) {
134 | if (index < componentIndex.size()) {
135 | if (i == componentIndex.get(index)) {
136 | index++;
137 | } else {
138 | result[j] = annotations[i];
139 | j++;
140 | }
141 | } else {
142 | result[j] = annotations[i];
143 | j++;
144 | }
145 |
146 | }
147 | return result;
148 | }
149 | return annotations;
150 | }
151 |
152 | private boolean isAnnotated(Class front, Class after) {
153 | if (front.isAnnotationPresent(after)) {
154 | return true;
155 | } else {
156 | if (front.isAnnotation()) {
157 | Annotation[] annotations = front.getAnnotations();
158 | for (Annotation annotation : annotations) {
159 | if (isAnnotated(annotation.annotationType(), after)) {
160 | return true;
161 | }
162 | }
163 | }
164 | }
165 | return false;
166 | }
167 |
168 | private BeanDefinition handleTypeAnnot(Class clazz, boolean isBeanAnnotated) throws Exception {
169 | Annotation[] annotations = clazz.getAnnotations();
170 | annotations = deDuplicationAnnotation(annotations);
171 | for (Annotation annotation : annotations) {
172 | log.debug(annotation + " is component ? " + annotation.annotationType().isAnnotationPresent(Component.class));
173 | if (annotation.annotationType() == Component.class) {
174 | //Component注解
175 | Component configAnnot = (Component) annotation;
176 | if (isBeanAnnotated) {
177 | return new BeanAnnotatedDefinition(getBeanName(configAnnot.name(), clazz), clazz);
178 | } else {
179 | return new BeanDefinition(getBeanName(configAnnot.name(), clazz), clazz);
180 | }
181 | } else if (annotation.annotationType().isAnnotationPresent(Component.class)) {
182 | //Configuration
183 | if (annotation.annotationType() == Configuration.class) {
184 | Configuration configAnnot = (Configuration) annotation;
185 | if (isBeanAnnotated) {
186 | return new BeanAnnotatedDefinition(getBeanName(configAnnot.name(), clazz), clazz);
187 | } else {
188 | return new BeanDefinition(getBeanName(configAnnot.name(), clazz), clazz);
189 | }
190 | }
191 | }
192 | }
193 | //有其他的注解,这些的解析交给子类完成
194 | return handleIntegrationAnnotation(clazz);
195 | }
196 |
197 | private void registerBean(BeanDefinition beanDefinition) throws Exception {
198 | log.debug("bean: {}", beanDefinition);
199 | if (getRegisterBeans().putIfAbsent(beanDefinition.getId(), beanDefinition) != null) {
200 | throw new BeanDefinitionException(String.format("bean is duplicate,bean name is '%s'", beanDefinition.getId()));
201 | }
202 | }
203 |
204 | private void handleFieldAnnot(Class clazz, BeanDefinition beanDefinition) throws Exception {
205 | Field[] fields = clazz.getDeclaredFields();
206 | for (Field field : fields) {
207 | Annotation[] annotations = field.getAnnotations();
208 | for (Annotation annotation : annotations) {
209 | if (annotation instanceof Value) {
210 | Value valueAnnot = (Value) annotation;
211 | //TODO 类型转化
212 | if (field.getType().equals(String.class)) {
213 | String configValue = valueAnnot.value();
214 | beanDefinition.addProperty(new BeanPropertyValue(field.getName(), getConfigValue(PlaceholderPraser.prase(configValue))));
215 | } else {
216 | throw new BeanDefinitionException(
217 | String.format("sorry, the field '%s', '@Value' only support String!!! , class: %s",
218 | field.getName(), clazz.getName()));
219 | }
220 | } else if (annotation instanceof Inject) {
221 | Inject injectAnnot = (Inject) annotation;
222 | BeanReference beanReference = new BeanReference(getBeanName(injectAnnot.name(), field.getType()));
223 | beanDefinition.addProperty(new BeanPropertyValue(field.getName(), beanReference));
224 | }
225 | }
226 | }
227 | }
228 |
229 | private Map handleMethodAnnotAndRegister(Class clazz) throws BeanDefinitionException {
230 | Map methodInfos = new HashMap<>();
231 | Method[] methods = clazz.getDeclaredMethods();
232 | for (Method method : methods) {
233 | Annotation[] annotations = method.getAnnotations();
234 | for (Annotation annotation : annotations) {
235 | if (annotation instanceof Bean) {
236 | if (method.getParameterCount() > 0) {
237 | throw new BeanDefinitionException(String.format("{} ,method annotated by '@Bean' is not support parameter, so let parameter blank", method));
238 | }
239 | Bean beanAnnot = (Bean) annotation;
240 | String beanName = getBeanName(beanAnnot.name(), method.getName());
241 | BeanDefinition beanDefinition = new BeanDefinition(beanName, method.getReturnType());
242 | methodInfos.put(method.getName(), beanName);
243 | getRegisterBeans().putIfAbsent(beanDefinition.getId(), beanDefinition);
244 | }
245 | }
246 | }
247 | return methodInfos;
248 | }
249 |
250 | public void setScanPackages(List scanPackages) {
251 | this.scanPackages.addAll(scanPackages);
252 | }
253 |
254 | }
255 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/beans/reader/AutoConfigBeanDefinitionReader.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans.reader;
2 |
3 | import com.tg.tiny4j.commons.constants.ConfigurationElement;
4 | import com.tg.tiny4j.core.ioc.beans.BeanDefinition;
5 | import org.apache.commons.lang3.StringUtils;
6 |
7 | import java.util.Arrays;
8 |
9 | /**
10 | * Created by twogoods on 16/10/29.
11 | */
12 | public class AutoConfigBeanDefinitionReader extends AnnotationBeanDefinitionReader {
13 |
14 | private void initConfig() throws Exception {
15 | //默认取application.properties
16 | loadConfig(ConfigurationElement.DEFAULT_CONFIG_FILE);
17 | //设置扫描的包
18 | String packages = getConfigValue(ConfigurationElement.COMPONENTSCAN);
19 | if (!StringUtils.isEmpty(packages)) {
20 | setScanPackages(Arrays.asList(packages.split(",")));
21 | }
22 | }
23 |
24 | @Override
25 | public void loadResource() throws Exception {
26 | initConfig();
27 | super.loadResource();
28 | }
29 |
30 | @Override
31 | public BeanDefinition handleIntegrationAnnotation(Class clazz) throws Exception {
32 | return null;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/beans/reader/BeanDefinitionReader.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans.reader;
2 |
3 | import com.tg.tiny4j.core.ioc.beans.BeanDefinition;
4 |
5 | import java.util.Map;
6 |
7 | /**
8 | * Created by twogoods on 16/10/26.
9 | */
10 | public interface BeanDefinitionReader {
11 |
12 | void loadResource() throws Exception;
13 |
14 | Map getRegisterBeans();
15 |
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/beans/reader/ClassScanner.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans.reader;
2 |
3 | import org.apache.commons.io.IOUtils;
4 | import org.apache.commons.lang3.StringUtils;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | import java.io.File;
9 | import java.io.FileNotFoundException;
10 | import java.io.IOException;
11 | import java.net.JarURLConnection;
12 | import java.net.URL;
13 | import java.net.URLConnection;
14 | import java.util.Enumeration;
15 | import java.util.HashSet;
16 | import java.util.List;
17 | import java.util.Set;
18 | import java.util.jar.JarEntry;
19 | import java.util.jar.JarFile;
20 | import java.util.jar.JarInputStream;
21 |
22 | /**
23 | * Created by twogoods on 16/10/28.
24 | */
25 | public class ClassScanner {
26 | private static final Logger log = LoggerFactory.getLogger(ClassScanner.class);
27 | public static Set getClasses(List packages) throws Exception {
28 | Set classes = new HashSet();
29 | for (String packageName : packages) {
30 | if (StringUtils.isEmpty(packageName)) {
31 | continue;
32 | }
33 | getClassByPackage(packageName.replace(".", File.separator), classes);
34 | }
35 | return classes;
36 | }
37 |
38 | private static void getClassByPackage(String packageName, Set classes) throws Exception {
39 | Enumeration baseURLs = ClassScanner.class.getClassLoader().getResources(packageName);
40 | URL baseURL = null;
41 | while (baseURLs.hasMoreElements()) {
42 | baseURL = baseURLs.nextElement();
43 | if (baseURL != null) {
44 | log.debug("componentscan find: {}",baseURL.toString());
45 | String protocol = baseURL.getProtocol();
46 | String basePath = baseURL.getFile();
47 | if ("jar".equals(protocol)) {
48 | //实际运行中看到了这样的形式的jar目录 /BOOT-INF/classes!/com ,classes是一个目录,去掉后面的!,原因还没弄明白.
49 | basePath = basePath.replace("classes!", "classes");
50 | String[] paths = basePath.split("jar!/");
51 | if (paths.length == 2) {
52 | findFileInJar(paths[0] + "jar!/", paths[1], classes);
53 | } else if (paths.length > 2) {
54 | int index = basePath.lastIndexOf("jar!/") + "jar".length();
55 | String lastJarPath = basePath.substring(0, index);
56 | String packagepath = basePath.substring(index + "!/".length(), basePath.length());
57 | findFileInJarWithinJar(lastJarPath, packagepath, classes);
58 | }
59 | } else {
60 | getClassesInFile(basePath, packageName, classes);
61 | }
62 | }
63 | }
64 | }
65 |
66 | private static void findFileInJar(String filePath, String packagePath, Set classes) throws IOException {
67 | URL url = new URL("jar", null, 0, filePath);
68 | URLConnection con = url.openConnection();
69 | if (con instanceof JarURLConnection) {
70 | JarURLConnection result = (JarURLConnection) con;
71 | JarFile jarFile = result.getJarFile();
72 | for (final Enumeration enumJar = jarFile.entries(); enumJar.hasMoreElements(); ) {
73 | JarEntry entry = enumJar.nextElement();
74 | filterClass(entry.getName(), packagePath, classes);
75 | }
76 | jarFile.close();
77 | }
78 | }
79 |
80 | private static void findFileInJarWithinJar(String filePath, String packagePath, Set classes) throws IOException {
81 | URL url = new URL("jar", null, 0, filePath);
82 | URLConnection con = url.openConnection();
83 | if (con instanceof JarURLConnection) {
84 | JarURLConnection jarURLConnection = (JarURLConnection) con;
85 | JarInputStream jarInputStream = new JarInputStream(jarURLConnection.getInputStream());
86 | JarEntry entry;
87 | while ((entry = jarInputStream.getNextJarEntry()) != null) {
88 | filterClass(entry.getName(), packagePath, classes);
89 | }
90 | IOUtils.closeQuietly(jarInputStream);
91 | }
92 | }
93 |
94 | private static void filterClass(String filePath, String packageName, Set classes) {
95 | if (filePath.startsWith(packageName) && filePath.endsWith(".class")) {
96 | classes.add(getWholeClassName(filePath));
97 | }
98 | }
99 |
100 |
101 | public static void getClassesInFile(String filePath, String packagePath, Set classes) throws Exception {
102 | File file = new File(filePath);
103 | if (!file.exists()) {
104 | throw new FileNotFoundException("check component-scan config, file or directory not found, path is " + filePath);
105 | }
106 | for (String fileName : file.list()) {
107 | String childFilePath = filePath;
108 | if (filePath.endsWith("/")) {
109 | childFilePath = childFilePath + fileName;
110 | } else {
111 | childFilePath = childFilePath + File.separator + fileName;
112 | }
113 | if (new File(childFilePath).isDirectory()) {
114 | getClassesInFile(childFilePath, packagePath, classes);
115 | } else if (fileName.endsWith(".class")) {
116 | String className = getWholeClassName(childFilePath);
117 | classes.add(className);
118 | }
119 | }
120 | }
121 |
122 | private static String getWholeClassName(String filePath) {
123 | if (filePath.indexOf("classes/") != -1) {
124 | return filePath.substring(filePath.indexOf("classes/") + "classes/".length(),
125 | filePath.indexOf(".class")).replaceAll("/", ".");
126 | }
127 | return filePath.substring(0, filePath.indexOf(".class")).replaceAll("/", ".");
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/beans/reader/PackageChecker.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans.reader;
2 |
3 | import java.util.Collections;
4 | import java.util.Comparator;
5 | import java.util.LinkedList;
6 | import java.util.List;
7 |
8 | /**
9 | * Created by twogoods on 16/10/29.
10 | */
11 | public class PackageChecker {
12 | /**
13 | * 多个包名去除有包涵关系的包
14 | *
15 | * @param arr
16 | * @return
17 | */
18 | protected static List deDuplicatePackage(String[] arr) {
19 | List list = new LinkedList<>();
20 | for (String item : arr) {
21 | list.add(item);
22 | }
23 | //从短到长排序
24 | Collections.sort(list, new Comparator() {
25 | @Override
26 | public int compare(String o1, String o2) {
27 | return o1.length() > o2.length() ? 0 : 1;
28 | }
29 | });
30 | for (int i = 0; i < list.size(); i++) {
31 | for (int j = list.size() - 1; i < j; j--) {
32 | if (list.get(j).contains(list.get(i))) {
33 | list.remove(j);
34 | }
35 | }
36 | }
37 | return list;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/beans/reader/PlaceholderPraser.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans.reader;
2 |
3 |
4 | /**
5 | * Created by twogoods on 16/10/29.
6 | */
7 | public class PlaceholderPraser {
8 |
9 | public static KeyAndDefault prase(String config) {
10 | if (config.startsWith("${") && config.endsWith("}")) {
11 | String subConfig = config.substring(2, config.length() - 1);
12 | String[] configAndDefault = subConfig.split(":");
13 | if (configAndDefault.length == 1) {
14 | return new KeyAndDefault(configAndDefault[0], null);
15 | } else {
16 | return new KeyAndDefault(configAndDefault[0], configAndDefault[1]);
17 | }
18 | }
19 | return new KeyAndDefault(config, null);
20 | }
21 |
22 | public static class KeyAndDefault {
23 | private String name;
24 | private String defaultValue;
25 |
26 | private KeyAndDefault(String name, String defaultValue) {
27 | this.name = name;
28 | this.defaultValue = defaultValue;
29 | }
30 |
31 | public String getName() {
32 | return name;
33 | }
34 |
35 | public String getDefaultValue() {
36 | return defaultValue;
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/beans/reader/XmlBeanDefinitionReader.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans.reader;
2 |
3 | import com.tg.tiny4j.commons.utils.Validate;
4 | import com.tg.tiny4j.core.ioc.beans.BeanDefinition;
5 | import com.tg.tiny4j.core.ioc.beans.BeanPropertyValue;
6 | import com.tg.tiny4j.core.ioc.beans.BeanReference;
7 | import com.tg.tiny4j.core.ioc.exception.BeanDefinitionException;
8 | import com.tg.tiny4j.core.ioc.resource.ResourceLoad;
9 | import org.apache.commons.lang3.StringUtils;
10 | import org.slf4j.Logger;
11 | import org.slf4j.LoggerFactory;
12 | import org.w3c.dom.Document;
13 | import org.w3c.dom.Element;
14 | import org.w3c.dom.Node;
15 | import org.w3c.dom.NodeList;
16 |
17 | import javax.xml.parsers.DocumentBuilder;
18 | import javax.xml.parsers.DocumentBuilderFactory;
19 | import java.io.InputStream;
20 | import java.util.List;
21 |
22 | /**
23 | * Created by twogoods on 16/10/25.
24 | */
25 | public class XmlBeanDefinitionReader extends AnnotationBeanDefinitionReader {
26 | private static Logger log = LoggerFactory.getLogger(XmlBeanDefinitionReader.class);
27 |
28 | private String location;
29 |
30 | public XmlBeanDefinitionReader(String location) {
31 | this.location = location;
32 | }
33 |
34 | @Override
35 | public void loadResource() throws Exception {
36 | log.debug("XmlBeanDefinitionReader load...");
37 | InputStream inputStream = ResourceLoad.getInstance().loadResource(location).getInputStream();
38 | try {
39 | DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
40 | DocumentBuilder docBuilder = factory.newDocumentBuilder();
41 | Document doc = docBuilder.parse(inputStream);
42 | Element root = doc.getDocumentElement();
43 | initConfig(root);
44 | //解析xml里配置的bean
45 | praseBeanDefinitions(root);
46 | //开始扫描注解的bean
47 | super.loadResource();
48 | } finally {
49 | inputStream.close();
50 | }
51 | }
52 |
53 | @Override
54 | public BeanDefinition handleIntegrationAnnotation(Class clazz) throws Exception {
55 | return null;
56 | }
57 |
58 | /**
59 | * config默认在classpath下取
60 | *
61 | * @param root
62 | */
63 | private void initConfig(Element root) throws Exception {
64 | NodeList propertieslist = root.getElementsByTagName("configs");
65 | if (propertieslist.getLength() != 1) {
66 | throw new BeanDefinitionException("In XML, should be unique.");
67 | }
68 | if (!(propertieslist.item(0) instanceof Element)) {
69 | return;
70 | }
71 | Element configRoot = (Element) propertieslist.item(0);
72 | //配置文件
73 | NodeList propertyFiles = configRoot.getElementsByTagName("property-file");
74 | if (propertyFiles.getLength() > 0) {
75 | String filesPath = propertyFiles.item(0).getTextContent();
76 | if (StringUtils.isEmpty(filesPath)) {
77 | return;
78 | }
79 | String[] pathArr = filesPath.split(",");
80 | for (String filePath : pathArr) {
81 | loadConfig(filePath);
82 | }
83 | } else {
84 | //默认取application.properties
85 | loadConfig("application.properties");
86 | }
87 | //设置扫描的包
88 | NodeList packageFiles = configRoot.getElementsByTagName("component-scan");
89 | if (packageFiles.getLength() > 0) {
90 | String packageNames = packageFiles.item(0).getTextContent();
91 | packageNames = getConfigValue(PlaceholderPraser.prase(packageNames));
92 | if (StringUtils.isEmpty(packageNames)) {
93 | return;
94 | }
95 | String[] packageArr = packageNames.split(",");
96 | List packages = PackageChecker.deDuplicatePackage(packageArr);
97 | setScanPackages(packages);
98 | }
99 | }
100 |
101 | private void praseBeanDefinitions(Element root) throws Exception {
102 | NodeList list = root.getElementsByTagName("bean");
103 | for (int i = 0; i < list.getLength(); i++) {
104 | Node node = list.item(i);
105 | if (node instanceof Element) {
106 | Element ele = (Element) node;
107 | readBean(ele);
108 | }
109 | }
110 | }
111 |
112 | private void readBean(Element ele) throws Exception {
113 | String className = ele.getAttribute("class");
114 | if (Validate.isEmpty(className)) {
115 | throw new BeanDefinitionException("Bean definition need 'class' property");
116 | }
117 | String id = ele.getAttribute("id");
118 | if (Validate.isEmpty(id)) {
119 | id = getBeanNameByClassName(className);
120 | }
121 | BeanDefinition beanDefinition = new BeanDefinition(id, className);
122 | processProperty(ele, beanDefinition);
123 | if (getRegisterBeans().putIfAbsent(id, beanDefinition) != null) {
124 | throw new BeanDefinitionException(String.format("bean is duplicate,bean name is '%s'", id));
125 | }
126 | }
127 |
128 |
129 | private void processProperty(Element ele, BeanDefinition beanDefinition) throws Exception {
130 | NodeList propertyNode = ele.getElementsByTagName("property");
131 | for (int i = 0; i < propertyNode.getLength(); i++) {
132 | Node node = propertyNode.item(i);
133 | if (node instanceof Element) {
134 | Element propertyEle = (Element) node;
135 | String name = propertyEle.getAttribute("name");
136 | if (Validate.isEmpty(name)) {
137 | throw new BeanDefinitionException("Bean definition need 'name' property");
138 | }
139 | String value = propertyEle.getAttribute("value");
140 | String ref = propertyEle.getAttribute("ref");
141 | if (!Validate.isEmpty(value)) {
142 | beanDefinition.addProperty(new BeanPropertyValue(name, value));
143 | } else if (!Validate.isEmpty(ref)) {
144 | BeanReference beanReference = new BeanReference(ref);
145 | beanDefinition.addProperty(new BeanPropertyValue(name, beanReference));
146 | } else {
147 | throw new BeanDefinitionException("Bean definition need 'name' property");
148 | }
149 | }
150 | }
151 | }
152 | }
153 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/context/AbstractApplicationContext.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.context;
2 |
3 | import com.tg.tiny4j.core.ioc.beans.BeanDefinition;
4 | import com.tg.tiny4j.core.ioc.beans.factory.AbstractBeanFactory;
5 |
6 | /**
7 | * Created by twogoods on 16/10/25.
8 | */
9 | public abstract class AbstractApplicationContext implements ApplicationContext{
10 | protected AbstractBeanFactory beanFactory;
11 |
12 | protected void refresh() throws Exception {
13 | registerBeans();
14 | //初始化容器上下文类
15 | instanceContextHolder();
16 | //预先初始化所有的bean
17 | instanceBeanFactory();
18 | }
19 |
20 | protected void registerBeans() throws Exception {}
21 |
22 | /**
23 | *增加一个名为applicationContextHolder的bean保存容器上下文
24 | */
25 | private void instanceContextHolder(){
26 | BeanDefinition beanDefinition=new BeanDefinition("applicationContextHolder",ApplicationContextHolder.class);
27 | beanDefinition.setBean(new ApplicationContextHolder(this));
28 | beanFactory.addBeanDefinition("applicationContextHolder",beanDefinition);
29 | }
30 |
31 | public void instanceBeanFactory() throws Exception {
32 | beanFactory.preInstantiateSingletons();
33 | }
34 |
35 | @Override
36 | public Object getBean(String name) throws Exception {
37 | return beanFactory.getBean(name);
38 | }
39 |
40 | @Override
41 | public T getBean(String name, Class clazz) throws Exception {
42 | return beanFactory.getBean(name,clazz);
43 | }
44 | @Override
45 | public boolean containsBean(String name) throws Exception {
46 | return beanFactory.containsBean(name);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/context/ApplicationContext.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.context;
2 |
3 | import com.tg.tiny4j.core.ioc.beans.factory.BeanFactory;
4 |
5 | /**
6 | * Created by twogoods on 16/10/25.
7 | */
8 | public interface ApplicationContext extends BeanFactory {
9 | }
10 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/context/ApplicationContextHolder.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.context;
2 |
3 | /**
4 | * Created by twogoods on 16/10/25.
5 | */
6 | public class ApplicationContextHolder {
7 | private ApplicationContext applicationContext;
8 |
9 | public ApplicationContextHolder(ApplicationContext applicationContext) {
10 | this.applicationContext = applicationContext;
11 | }
12 | Object getBean(String name) throws Exception{
13 | return applicationContext.getBean(name);
14 | }
15 |
16 | T getBean(String name, Class clazz) throws Exception{
17 | return applicationContext.getBean(name,clazz);
18 | }
19 |
20 | boolean containsBean(String name) throws Exception{
21 | return applicationContext.containsBean(name);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/context/ClassPathXmlApplicationContext.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.context;
2 |
3 | import com.tg.tiny4j.core.ioc.beans.factory.DefaultBeanFactory;
4 | import com.tg.tiny4j.core.ioc.beans.reader.BeanDefinitionReader;
5 | import com.tg.tiny4j.core.ioc.beans.reader.XmlBeanDefinitionReader;
6 |
7 | /**
8 | * Created by twogoods on 16/10/25.
9 | */
10 | public class ClassPathXmlApplicationContext extends AbstractApplicationContext{
11 | private String configLocation;
12 |
13 | public ClassPathXmlApplicationContext(String configLocation) throws Exception {
14 | this.configLocation = configLocation;
15 | refresh();
16 | }
17 |
18 | protected void registerBeans() throws Exception {
19 | BeanDefinitionReader beanDefinitionReader=new XmlBeanDefinitionReader(configLocation);
20 | beanDefinitionReader.loadResource();
21 | beanFactory=new DefaultBeanFactory();
22 | beanFactory.addBeanDefinition(beanDefinitionReader.getRegisterBeans());
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/exception/BeanDefinitionException.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.exception;
2 |
3 | /**
4 | * Created by twogoods on 16/10/26.
5 | */
6 | public class BeanDefinitionException extends Exception{
7 | public BeanDefinitionException(String message) {
8 | super(message);
9 | }
10 |
11 | public BeanDefinitionException(String message, Throwable cause) {
12 | super(message, cause);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/exception/BeanException.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.exception;
2 |
3 | /**
4 | * Created by twogoods on 16/10/26.
5 | */
6 | public class BeanException extends Exception{
7 | public BeanException(String message) {
8 | super(message);
9 | }
10 |
11 | public BeanException(String message, Throwable cause) {
12 | super(message, cause);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/exception/ConfigurationException.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.exception;
2 |
3 | /**
4 | * Created by twogoods on 16/10/29.
5 | */
6 | public class ConfigurationException extends Exception{
7 | public ConfigurationException(String message) {
8 | super(message);
9 | }
10 |
11 | public ConfigurationException(String message, Throwable cause) {
12 | super(message, cause);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/exception/PropertyDuplicateException.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.exception;
2 |
3 | /**
4 | * Created by twogoods on 16/10/26.
5 | */
6 | public class PropertyDuplicateException extends Exception {
7 | public PropertyDuplicateException(String message) {
8 | super(message);
9 | }
10 |
11 | public PropertyDuplicateException(String message, Throwable cause) {
12 | super(message, cause);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/resource/Resource.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.resource;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 |
6 | /**
7 | * Created by twogoods on 16/10/25.
8 | */
9 | public interface Resource {
10 |
11 | InputStream getInputStream() throws IOException;
12 | }
13 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/resource/ResourceLoad.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.resource;
2 |
3 | import com.tg.tiny4j.core.ioc.exception.ConfigurationException;
4 |
5 | import java.io.InputStream;
6 | import java.net.URL;
7 | import java.util.Properties;
8 |
9 | /**
10 | * Created by twogoods on 16/10/25.
11 | */
12 | public class ResourceLoad {
13 |
14 | private static ResourceLoad resourceLoad = new ResourceLoad();
15 |
16 | public static ResourceLoad getInstance() {
17 | return resourceLoad;
18 | }
19 |
20 | private ResourceLoad() {
21 | }
22 |
23 | public Resource loadResource(String location) {
24 | URL url = getClass().getClassLoader().getResource(location);
25 | return new UrlResource(url);
26 | }
27 |
28 | public Properties loadConfig(String path) throws Exception {
29 | InputStream in = getClass().getClassLoader().getResourceAsStream(path);
30 | if(in==null){
31 | throw new ConfigurationException(String.format("'%s' is not exist",path));
32 | }
33 | try {
34 | Properties prop = new Properties();
35 | prop.load(in);
36 | return prop;
37 | } finally {
38 | in.close();
39 | }
40 | }
41 |
42 | }
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/ioc/resource/UrlResource.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.resource;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.net.URL;
6 | import java.net.URLConnection;
7 |
8 | /**
9 | * Created by twogoods on 16/10/25.
10 | */
11 | public class UrlResource implements Resource {
12 | private URL url;
13 |
14 | public UrlResource(URL url) {
15 | this.url = url;
16 | }
17 |
18 | @Override
19 | public InputStream getInputStream() throws IOException {
20 | URLConnection con=url.openConnection();
21 | return con.getInputStream();
22 | }
23 |
24 | public URL getUrl() {
25 | return url;
26 | }
27 |
28 | public void setUrl(URL url) {
29 | this.url = url;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/web/integration/BootAppBeanDefinitionReader.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.web.integration;
2 |
3 | import com.tg.tiny4j.core.ioc.beans.BeanDefinition;
4 | import com.tg.tiny4j.core.ioc.beans.reader.AutoConfigBeanDefinitionReader;
5 |
6 | /**
7 | * Description:
8 | *
9 | * @author twogoods
10 | * @version 0.1
11 | * @since 2017-03-31
12 | */
13 | public class BootAppBeanDefinitionReader extends AutoConfigBeanDefinitionReader{
14 | private HandleAnnotation handle;
15 |
16 | public BootAppBeanDefinitionReader(HandleAnnotation handle) {
17 | this.handle = handle;
18 | }
19 |
20 | @Override
21 | public BeanDefinition handleIntegrationAnnotation(Class clazz) throws Exception {
22 | return handle.handle(clazz);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/web/integration/ContextListener/AbstractBootContextListener.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.web.integration.ContextListener;
2 |
3 | import com.tg.tiny4j.commons.constants.WebApplicationEnvironment;
4 | import com.tg.tiny4j.core.web.integration.HandleRegistry;
5 | import com.tg.tiny4j.core.web.integration.context.BootApplicationContext;
6 | import com.tg.tiny4j.core.web.integration.context.WebApplicationContext;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | import javax.servlet.ServletContextEvent;
11 | import javax.servlet.ServletContextListener;
12 |
13 | /**
14 | * Description:
15 | *
16 | * @author twogoods
17 | * @version 0.1
18 | * @since 2017-03-31
19 | */
20 | public abstract class AbstractBootContextListener implements ServletContextListener {
21 | private static Logger log = LoggerFactory.getLogger(AbstractBootContextListener.class);
22 |
23 | private WebApplicationContext webApplicationContext;
24 | private HandleRegistry registry = new HandleRegistry();
25 |
26 | public abstract void registerHandle(HandleRegistry registry);
27 |
28 | public abstract void requestMapInitialized(ServletContextEvent servletContextEvent, WebApplicationContext applicationContext) throws Exception;
29 |
30 | @Override
31 | public void contextInitialized(ServletContextEvent servletContextEvent) {
32 | try {
33 | registerHandle(registry);
34 | webApplicationContext = new BootApplicationContext(registry.getHandle());
35 | requestMapInitialized(servletContextEvent, webApplicationContext);
36 | servletContextEvent.getServletContext().setAttribute(WebApplicationEnvironment.RUN_MODE, WebApplicationEnvironment.CONTAINER_MODE);
37 | // servletContextEvent.getServletContext().setAttribute("root_applicationcontext", webApplicationContext);
38 | } catch (Exception e) {
39 | log.error("Context initialization failed", e);
40 | }
41 | }
42 |
43 | @Override
44 | public void contextDestroyed(ServletContextEvent servletContextEvent) {
45 | log.info("SingleRestLoaderListener destroyed...");
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/web/integration/ContextListener/AbstractWebContextListener.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.web.integration.ContextListener;
2 |
3 | import com.tg.tiny4j.commons.constants.WebApplicationEnvironment;
4 | import com.tg.tiny4j.core.web.integration.HandleRegistry;
5 | import com.tg.tiny4j.core.web.integration.context.ServletContainerApplicationContext;
6 | import com.tg.tiny4j.core.web.integration.context.WebApplicationContext;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | import javax.servlet.ServletContextEvent;
11 | import javax.servlet.ServletContextListener;
12 |
13 | /**
14 | * Created by twogoods on 16/11/5.
15 | */
16 | public abstract class AbstractWebContextListener implements ServletContextListener {
17 |
18 | private static Logger log = LoggerFactory.getLogger(AbstractWebContextListener.class);
19 |
20 | private WebApplicationContext webApplicationContext;
21 | private HandleRegistry registry = new HandleRegistry();
22 |
23 | public abstract void registerHandle(HandleRegistry registry);
24 |
25 | public abstract void requestMapInitialized(ServletContextEvent servletContextEvent, WebApplicationContext applicationContext) throws Exception;
26 |
27 | @Override
28 | public void contextInitialized(ServletContextEvent servletContextEvent) {
29 | try {
30 | registerHandle(registry);
31 | webApplicationContext = new ServletContainerApplicationContext(registry.getHandle());
32 | requestMapInitialized(servletContextEvent, webApplicationContext);
33 | servletContextEvent.getServletContext().setAttribute(WebApplicationEnvironment.RUN_MODE, WebApplicationEnvironment.CONTAINER_MODE);
34 | // servletContextEvent.getServletContext().setAttribute("root_applicationcontext", webApplicationContext);
35 | } catch (Exception e) {
36 | log.error("Context initialization failed", e);
37 | }
38 | }
39 |
40 | @Override
41 | public void contextDestroyed(ServletContextEvent servletContextEvent) {
42 | log.info("SingleRestLoaderListener destroyed...");
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/web/integration/HandleAnnotation.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.web.integration;
2 |
3 | import com.tg.tiny4j.core.ioc.beans.BeanDefinition;
4 |
5 | /**
6 | * Created by twogoods on 16/11/5.
7 | */
8 | public interface HandleAnnotation {
9 | BeanDefinition handle(Class clazz) throws Exception;
10 | }
11 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/web/integration/HandleRegistry.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.web.integration;
2 |
3 | /**
4 | * Created by twogoods on 16/11/5.
5 | */
6 | public class HandleRegistry {
7 | private HandleAnnotation handle;
8 |
9 | public void addHandle(HandleAnnotation handle){
10 | this.handle=handle;
11 | }
12 |
13 | public HandleAnnotation getHandle() {
14 | return handle;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/web/integration/WebAppBeanDefinitionReader.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.web.integration;
2 |
3 | import com.tg.tiny4j.core.ioc.beans.BeanDefinition;
4 | import com.tg.tiny4j.core.ioc.beans.reader.XmlBeanDefinitionReader;
5 |
6 |
7 | /**
8 | * Created by twogoods on 16/11/1.
9 | */
10 | public class WebAppBeanDefinitionReader extends XmlBeanDefinitionReader {
11 |
12 | private HandleAnnotation handle;
13 |
14 | public WebAppBeanDefinitionReader(String location, HandleAnnotation handle) {
15 | super(location);
16 | this.handle = handle;
17 | }
18 |
19 | public WebAppBeanDefinitionReader(HandleAnnotation handle) {
20 | this("application.xml", handle);
21 | }
22 |
23 | @Override
24 | public BeanDefinition handleIntegrationAnnotation(Class clazz) throws Exception {
25 | return handle.handle(clazz);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/web/integration/context/BootApplicationContext.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.web.integration.context;
2 |
3 | import com.tg.tiny4j.core.ioc.beans.factory.DefaultBeanFactory;
4 | import com.tg.tiny4j.core.web.integration.BootAppBeanDefinitionReader;
5 | import com.tg.tiny4j.core.web.integration.HandleAnnotation;
6 | /**
7 | * Description:
8 | *
9 | * @author twogoods
10 | * @version 0.1
11 | * @since 2017-03-31
12 | */
13 | public class BootApplicationContext extends WebApplicationContext {
14 | private HandleAnnotation handle;
15 |
16 | public BootApplicationContext(HandleAnnotation handle) throws Exception {
17 | super();
18 | this.handle = handle;
19 | refresh();
20 | }
21 |
22 | protected void registerBeans() throws Exception {
23 | BootAppBeanDefinitionReader bootAppBeanDefinitionReader = new BootAppBeanDefinitionReader(handle);
24 | //读取bean信息
25 | bootAppBeanDefinitionReader.loadResource();
26 | beanFactory = new DefaultBeanFactory();
27 | beanFactory.addBeanDefinition(bootAppBeanDefinitionReader.getRegisterBeans());
28 | }
29 | }
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/web/integration/context/ServletContainerApplicationContext.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.web.integration.context;
2 |
3 | import com.tg.tiny4j.core.ioc.beans.factory.DefaultBeanFactory;
4 | import com.tg.tiny4j.core.web.integration.HandleAnnotation;
5 | import com.tg.tiny4j.core.web.integration.WebAppBeanDefinitionReader;
6 |
7 | /**
8 | * Description:
9 | *
10 | * @author twogoods
11 | * @version 0.1
12 | * @since 2017-03-31
13 | */
14 | public class ServletContainerApplicationContext extends WebApplicationContext {
15 | private HandleAnnotation handle;
16 |
17 | public ServletContainerApplicationContext(HandleAnnotation handle) throws Exception {
18 | super();
19 | this.handle = handle;
20 | refresh();
21 | }
22 |
23 | protected void registerBeans() throws Exception {
24 | WebAppBeanDefinitionReader webAppBeanDefinitionReader = new WebAppBeanDefinitionReader(handle);
25 | //读取bean信息
26 | webAppBeanDefinitionReader.loadResource();
27 | beanFactory = new DefaultBeanFactory();
28 | beanFactory.addBeanDefinition(webAppBeanDefinitionReader.getRegisterBeans());
29 | }
30 | }
--------------------------------------------------------------------------------
/core/src/main/java/com/tg/tiny4j/core/web/integration/context/WebApplicationContext.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.web.integration.context;
2 |
3 | import com.tg.tiny4j.core.ioc.context.AbstractApplicationContext;
4 | import java.util.HashMap;
5 | import java.util.List;
6 | import java.util.Map;
7 |
8 | /**
9 | * Created by twogoods on 16/11/2.
10 | */
11 | public abstract class WebApplicationContext extends AbstractApplicationContext {
12 | public Map getBeans(List names) throws Exception {
13 | Map beans = new HashMap<>();
14 | for (String name : names) {
15 | beans.put(name, getBean(name));
16 | }
17 | return beans;
18 | }
19 | }
--------------------------------------------------------------------------------
/core/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | dataSource.driverClass=com.mysql.jdbc.Driver
2 | dataSource.url=jdbc:mysql://127.0.0.1:3306/test
3 | dataSource.monUser=root
4 | dataSource.password=
5 | dataSource.maxPoolSize=11
6 | dataSource.minPoolSize=5
7 | dataSource.maxStatements=8
--------------------------------------------------------------------------------
/core/src/main/resources/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/core/src/test/java/com/tg/tiny4j/core/aop/Add.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop;
2 |
3 | /**
4 | * Created by twogoods on 16/10/24.
5 | */
6 | public class Add{
7 |
8 | private String prop;
9 |
10 | public int add(int a, int b) {
11 | System.out.println("prop:"+prop);
12 | return a+b;
13 | }
14 |
15 | public int add(int a) {
16 | return a+a;
17 | }
18 |
19 |
20 | public String getProp() {
21 | return prop;
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/core/src/test/java/com/tg/tiny4j/core/aop/AddOperate.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop;
2 |
3 | /**
4 | * Created by twogoods on 16/10/30.
5 | */
6 | public class AddOperate implements Operate{
7 | private String prop;
8 | @Override
9 | public int cal(int a, int b) {
10 | System.out.println("method: cal(a,b)");
11 | //System.out.println("prop:"+prop);
12 | return a+b+cal(a);
13 | }
14 |
15 | @Override
16 | public int cal(int a) {
17 | System.out.println("method: cal(a)");
18 | return a+a;
19 | }
20 |
21 | @Override
22 | public int calno() {
23 | return 0;
24 | }
25 |
26 |
27 | public String getProp() {
28 | return prop;
29 | }
30 |
31 | public void setProp(String prop) {
32 | this.prop = prop;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/core/src/test/java/com/tg/tiny4j/core/aop/CglibDynamicAopProxyTest.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop;
2 |
3 | import com.tg.tiny4j.core.aop.advice.AopAdvice;
4 | import com.tg.tiny4j.core.aop.advice.Target;
5 | import com.tg.tiny4j.core.aop.exception.AdviceDefinitionException;
6 | import net.sf.cglib.proxy.Enhancer;
7 | import net.sf.cglib.proxy.MethodInterceptor;
8 | import net.sf.cglib.proxy.MethodProxy;
9 | import org.junit.Test;
10 |
11 | import java.io.File;
12 | import java.lang.reflect.Field;
13 | import java.lang.reflect.InvocationTargetException;
14 | import java.lang.reflect.Method;
15 | import java.util.Arrays;
16 |
17 | /**
18 | * Created by twogoods on 16/10/24.
19 | */
20 | public class CglibDynamicAopProxyTest {
21 | @Test
22 | public void test() throws Exception {
23 | AopAdvice aopAdvice = new AopAdvice();
24 | aopAdvice.setTarget(new Target(Add.class));
25 | aopAdvice.setInterceptor(new TestAopInterceptor());
26 | CglibAopProxy cglibDynamicAopProxy = new CglibAopProxy(aopAdvice);
27 | Add operate = (Add) cglibDynamicAopProxy.getProxy();
28 | System.out.println(operate.add(1, 2));
29 | }
30 |
31 |
32 |
33 | @Test
34 | public void originTest() throws Exception {
35 | Enhancer enhancer = new Enhancer();
36 | enhancer.setSuperclass(Add.class);
37 | enhancer.setCallback(new MethodInterceptor() {
38 | @Override
39 | public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
40 | throws Throwable {
41 | if (method.getDeclaringClass() != Object.class && method.getReturnType() == String.class) {
42 | return "Hello cglib!";
43 | } else {
44 | return proxy.invokeSuper(obj, args);
45 | }
46 | }
47 | });
48 | Add proxy = (Add) enhancer.create();
49 | System.out.println(proxy.getProp());
50 | System.out.println(proxy.getClass().getSuperclass());
51 | }
52 |
53 | @Test
54 | public void anotherTest() throws Exception {
55 | AopAdvice aopAdvice = new AopAdvice();
56 | aopAdvice.setTarget(new Target(Add.class));
57 | aopAdvice.setInterceptor(new TestAopInterceptor());
58 | CglibAopProxy cglibDynamicAopProxy = new CglibAopProxy(aopAdvice);
59 | Add operate = (Add) cglibDynamicAopProxy.getProxy();
60 | System.out.println("--------------field-------------");
61 | Field[] fields = operate.getClass().getFields();
62 | for (Field f : fields) {
63 | System.out.println(f);
64 | }
65 | //上面无法得到属性的field,利用这种方式给代理对象赋值
66 | Field f=Add.class.getDeclaredField("prop");
67 | f.setAccessible(true);
68 | f.set(operate,"twogoods");
69 | System.out.println(operate.getProp());
70 | }
71 |
72 | @Test
73 | public void autoSetTest() throws Exception {
74 | AopAdvice aopAdvice = new AopAdvice();
75 | aopAdvice.setTarget(new Target(Add.class));
76 | //TestAopInterceptor拦截了set方法,实现本质上与上一个测试类是一样的
77 | aopAdvice.setInterceptor(new TestAopInterceptor());
78 | AutoSetterCglibAopProxy cglibDynamicAopProxy = new AutoSetterCglibAopProxy(aopAdvice);
79 | Add operate = (Add) cglibDynamicAopProxy.getProxy();
80 |
81 | System.out.println(operate.add(1, 2));
82 |
83 | System.out.println("*******");
84 | Method setM = operate.getClass().getMethod("setProp", String.class);
85 | System.out.println(setM);
86 | setM.invoke(operate, "twogoods");
87 | System.out.println(operate.getProp());
88 | }
89 | }
--------------------------------------------------------------------------------
/core/src/test/java/com/tg/tiny4j/core/aop/JdkDynamicAopProxyTest.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop;
2 |
3 | import com.tg.tiny4j.core.aop.advice.AopAdvice;
4 | import com.tg.tiny4j.core.aop.advice.Target;
5 | import com.tg.tiny4j.core.aop.exception.AdviceDefinitionException;
6 | import org.junit.Test;
7 |
8 | import java.lang.reflect.Method;
9 |
10 | /**
11 | * Created by twogoods on 16/10/24.
12 | */
13 | public class JdkDynamicAopProxyTest {
14 |
15 | @Test
16 | public void test() throws Exception {
17 | AddOperate add=new AddOperate();
18 | add.setProp("jdk...");
19 | AopAdvice aopAdvice=new AopAdvice();
20 | aopAdvice.setTarget(new Target(add,AddOperate.class,AddOperate.class.getInterfaces()));
21 | aopAdvice.setInterceptor(new TestAopInterceptor());
22 | JdkDynamicAopProxy jdkDynamicAopProxy=new JdkDynamicAopProxy(aopAdvice);
23 | Operate addproxy=(Operate)jdkDynamicAopProxy.getProxy();
24 | //int result=addproxy.cal(2, 4);
25 |
26 | // Method m=addproxy.getClass().getDeclaredMethod("cal",int.class,int.class);
27 | // m.invoke(addproxy,2,4);
28 |
29 | addproxy.calno();
30 | }
31 | }
--------------------------------------------------------------------------------
/core/src/test/java/com/tg/tiny4j/core/aop/Operate.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop;
2 |
3 | /**
4 | * Created by twogoods on 16/10/24.
5 | */
6 | public interface Operate {
7 | int cal(int a,int b);
8 | int cal(int a);
9 | int calno();
10 | }
11 |
--------------------------------------------------------------------------------
/core/src/test/java/com/tg/tiny4j/core/aop/TestAopInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.aop;
2 |
3 | import com.tg.tiny4j.core.aop.advice.AopInterceptor;
4 | import com.tg.tiny4j.core.aop.advice.Methodinvocation;
5 | import org.apache.commons.lang3.text.WordUtils;
6 |
7 | import java.lang.reflect.Field;
8 | import java.util.Arrays;
9 |
10 | /**
11 | * Created by twogoods on 16/10/24.
12 | */
13 | public class TestAopInterceptor implements AopInterceptor {
14 | @Override
15 | public Object invoke(Methodinvocation invocation) throws Throwable {
16 | String methodName=invocation.getMethod().getName();
17 | if(methodName.startsWith("set")){
18 | Field f=invocation.getObjClass().getDeclaredField(getFieldNameBySetter(methodName));
19 | f.setAccessible(true);
20 | f.set(invocation.getTarget(), invocation.getArguments()[0]);
21 | System.out.println("do setter....");
22 | return null;
23 | }
24 | System.out.println(String.format("***--before--method:{%s},args:{%s}",invocation.getMethod().getName(), Arrays.asList(invocation.getArguments())));
25 | Object result=invocation.proceed();
26 | System.out.println(String.format("***--after--result:{%s}",result));
27 | return result;
28 | }
29 |
30 | private String getFieldNameBySetter(String setterName){
31 | return WordUtils.uncapitalize(setterName.substring(3));
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/core/src/test/java/com/tg/tiny4j/core/ioc/beans/reader/ConfigBean.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans.reader;
2 |
3 | import com.tg.tiny4j.core.ioc.annotation.*;
4 |
5 | /**
6 | * Created by twogoods on 16/10/31.
7 | */
8 | @Component
9 | @Configuration
10 | public class ConfigBean {
11 |
12 | @Value("${user.name:testname}")
13 | private String name;
14 | @Value("${user.pass}")
15 | private String pass;
16 |
17 | @Inject
18 | private ServiceBean serviceBean;
19 |
20 | @Bean
21 | public DaoBean beanAnnDao(){
22 | System.out.println("in ConfigBean do @Bean method: beanAnnDao");
23 | return new DaoBean();
24 | }
25 |
26 | @Bean
27 | public ServiceBean beanAnnService(){
28 | //new ServiceBean(beanAnnDao()); 还不支持构造器注入
29 | System.out.println("in ConfigBean do @Bean method: beanAnnService");
30 | ServiceBean newBean=new ServiceBean();
31 | newBean.setS1(name+"---"+serviceBean.getS1());
32 | newBean.setS2(pass+"---"+serviceBean.getS2());
33 | newBean.setDaoBean(beanAnnDao());
34 | return newBean;
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/core/src/test/java/com/tg/tiny4j/core/ioc/beans/reader/DaoBean.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans.reader;
2 |
3 | import com.tg.tiny4j.core.ioc.annotation.Component;
4 |
5 | /**
6 | * Created by twogoods on 16/10/29.
7 | */
8 | @Component
9 | public class DaoBean {
10 | public void execute(){
11 | System.out.println("sql execute...");
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/core/src/test/java/com/tg/tiny4j/core/ioc/beans/reader/LogBeanPostProcessor.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans.reader;
2 |
3 | import com.tg.tiny4j.core.ioc.beans.BeanPostProcessor;
4 |
5 | /**
6 | * Created by twogoods on 16/10/29.
7 | */
8 | public class LogBeanPostProcessor implements BeanPostProcessor {
9 | @Override
10 | public Object postProcessBeforeInitialization(Object bean, String beanName) {
11 | System.out.println(beanName+" do before...");
12 | return bean;
13 | }
14 |
15 | @Override
16 | public Object postProcessAfterInitialization(Object bean, String beanName) {
17 | System.out.println(beanName+" do after...");
18 | return bean;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/core/src/test/java/com/tg/tiny4j/core/ioc/beans/reader/ServiceBean.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans.reader;
2 |
3 | import com.tg.tiny4j.core.ioc.annotation.Component;
4 | import com.tg.tiny4j.core.ioc.annotation.Inject;
5 | import com.tg.tiny4j.core.ioc.annotation.Value;
6 |
7 | /**
8 | * Created by twogoods on 16/10/29.
9 | */
10 | @Component
11 | public class ServiceBean {
12 | @Value("${user.nick:test}")
13 | private String s1;
14 | @Value("${user.name:test}")
15 | private String s2;
16 |
17 | @Inject
18 | private DaoBean daoBean;
19 |
20 | public ServiceBean() {
21 | }
22 |
23 | public ServiceBean(DaoBean daoBean) {
24 | this.daoBean = daoBean;
25 | }
26 |
27 | public void service(){
28 | daoBean.execute();
29 | }
30 |
31 | @Override
32 | public String toString() {
33 | return "ServiceBean{" +
34 | "s1='" + s1 + '\'' +
35 | ", s2='" + s2 + '\'' +
36 | '}';
37 | }
38 |
39 | public String getS1() {
40 | return s1;
41 | }
42 |
43 | public void setS1(String s1) {
44 | this.s1 = s1;
45 | }
46 |
47 | public String getS2() {
48 | return s2;
49 | }
50 |
51 | public void setS2(String s2) {
52 | this.s2 = s2;
53 | }
54 |
55 | public void setDaoBean(DaoBean daoBean) {
56 | this.daoBean = daoBean;
57 | }
58 |
59 | public DaoBean getDaoBean() {
60 | return daoBean;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/core/src/test/java/com/tg/tiny4j/core/ioc/beans/reader/XmlBeanDefinitionReaderTest.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.beans.reader;
2 |
3 | import org.junit.Test;
4 |
5 |
6 | /**
7 | * Created by twogoods on 16/10/26.
8 | */
9 | public class XmlBeanDefinitionReaderTest {
10 |
11 | @Test
12 | public void testLoadResource() throws Exception {
13 | XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader("test.xml");
14 | beanDefinitionReader.loadResource();
15 | System.out.println(beanDefinitionReader.getRegisterBeans());
16 | assert beanDefinitionReader.getRegisterBeans().size() > 0;
17 | }
18 | }
--------------------------------------------------------------------------------
/core/src/test/java/com/tg/tiny4j/core/ioc/context/ClassPathXmlApplicationContextTest.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.context;
2 |
3 | import com.tg.tiny4j.core.ioc.beans.reader.ConfigBean;
4 | import com.tg.tiny4j.core.ioc.beans.reader.ServiceBean;
5 | import org.junit.Test;
6 |
7 | /**
8 | * Created by twogoods on 16/10/27.
9 | */
10 | public class ClassPathXmlApplicationContextTest {
11 | @Test
12 | public void test() throws Exception {
13 | System.out.println("1******************");
14 | ApplicationContext applicationContext = new ClassPathXmlApplicationContext("test.xml");
15 |
16 |
17 | // ServiceBean serviceBean=(ServiceBean)applicationContext.getBean("testService");
18 | // System.out.println(serviceBean);
19 | // serviceBean.service();
20 |
21 | System.out.println("2*******************");
22 |
23 | // ServiceBean serviceBean2=(ServiceBean)applicationContext.getBean("serviceBean");
24 | // System.out.println(serviceBean2);
25 | // serviceBean2.service();
26 |
27 | System.out.println("3*******************");
28 |
29 | //IOC上下文
30 | // ApplicationContextHolder holder=applicationContext.getBean("applicationContextHolder", ApplicationContextHolder.class);
31 | // System.out.println("holder get bean : "+holder.getBean("serviceBean"));
32 |
33 | System.out.println("4*******************");
34 | ConfigBean configBean=(ConfigBean)applicationContext.getBean("configBean");
35 | System.out.println("configbean get dao:"+configBean.beanAnnDao());
36 | System.out.println("configbean get service:"+configBean.beanAnnService().hashCode());
37 | ServiceBean beanAnnService=(ServiceBean)applicationContext.getBean("beanAnnService");
38 | System.out.println("application get service: "+beanAnnService.hashCode());
39 | System.out.println("application get dao: "+applicationContext.getBean("beanAnnDao"));
40 | beanAnnService.service();
41 | System.out.println(beanAnnService.getDaoBean().hashCode()+"---"+applicationContext.getBean("beanAnnDao").hashCode());
42 |
43 | }
44 |
45 | }
--------------------------------------------------------------------------------
/core/src/test/java/com/tg/tiny4j/core/ioc/resource/ResourceLoadTest.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.core.ioc.resource;
2 |
3 | import org.junit.Test;
4 |
5 | import java.io.IOException;
6 | import java.io.InputStream;
7 |
8 | /**
9 | * Created by twogoods on 16/10/25.
10 | */
11 | public class ResourceLoadTest {
12 | @Test
13 | public void test() throws IOException {
14 | Resource resource=ResourceLoad.getInstance().loadResource("test.xml");
15 | InputStream inputStream=resource.getInputStream();
16 | byte[] bytes=new byte[1024];
17 | inputStream.read(bytes);
18 | System.out.println(new String(bytes));
19 | inputStream.close();
20 | }
21 | }
--------------------------------------------------------------------------------
/core/src/test/resources/application.properties:
--------------------------------------------------------------------------------
1 | tiny4j.component-scan=com.tg.tiny4j.core.ioc.beans.reader
2 | user.name=twogoods
3 | user.pass=two
--------------------------------------------------------------------------------
/core/src/test/resources/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/core/src/test/resources/test.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | application.properties
5 | ${tiny4j.component-scan:com.tg}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.twogoods.tiny4j
8 | tiny4j
9 | pom
10 | 0.0.1
11 |
12 | rest
13 | web-test
14 | core
15 | commons
16 | web-containerembed
17 |
18 |
19 |
20 |
21 | UTF-8
22 | 1.7
23 | UTF-8
24 | 8.5.5
25 |
26 |
27 |
28 |
29 | junit
30 | junit
31 | 4.12
32 |
33 |
34 | org.slf4j
35 | slf4j-api
36 | 1.7.21
37 |
38 |
39 | org.slf4j
40 | slf4j-simple
41 | 1.7.16
42 | test
43 |
44 |
45 |
46 |
47 |
48 | org.apache.maven.plugins
49 | maven-compiler-plugin
50 | 3.1
51 |
52 | ${java.version}
53 | ${java.version}
54 | UTF-8
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/rest/README.md:
--------------------------------------------------------------------------------
1 | # rest
2 | web框架支持rest,json格式,不提供MVC的V了,基于自己以前的使用经历,会实现SpringMvc里高频的功能以及对一些SpringMvc中不好处理的地方提供更好的支持。
3 | rest模块在设计时就考虑希望可以拆开IOC独立实现,IOC可以单独使用,rest也可以离开IOC单独使用。这样拆开来代码实现也清晰一些,这样我自己实现或者其他同学想了解一个简单的web实现都更容易一些。
4 | ### SpringBoot风格的可执行Jar
5 | SpringBoot以约定大于配置的思想极大的简化了spring项目的配置内容,并提供了一个内嵌容器的可执行Jar,使得部署、管理都更加容易。rest也在尝试模仿SpringBoot的风格,做了一个简化的实现。
6 | #### helloworld
7 | ```
8 | //boot应用请继承AbstractBootContextListener
9 | public class BootAppLoaderListener extends AbstractBootContextListener {
10 | private static final Logger log = LogManager.getLogger(BootAppLoaderListener.class);
11 |
12 | private final WebAppControllerReader webAppControllerReader = new WebAppControllerReader();
13 |
14 | @Override
15 | public void registerHandle(HandleRegistry registry) {
16 | HandleAnnotation handle = new HandleAnnotation() {
17 | @Override
18 | public BeanDefinition handle(Class clazz) throws Exception {
19 | BaseInfo baseInfo = webAppControllerReader.read(clazz);
20 | if (Validate.isEmpty(baseInfo)) {
21 | return null;
22 | } else {
23 | return new BeanDefinition(baseInfo.getName(), baseInfo.getClassName());
24 | }
25 | }
26 | };
27 | registry.addHandle(handle);
28 | }
29 |
30 | @Override
31 | public void requestMapInitialized(ServletContextEvent servletContextEvent, WebApplicationContext applicationContext) throws Exception {
32 | webAppControllerReader.initRequestMap();
33 | webAppControllerReader.setInstances(applicationContext.getBeans(webAppControllerReader.getControllerName()));
34 | servletContextEvent.getServletContext().setAttribute(WebApplicationEnvironment.WEBREQUESTMAPPER, webAppControllerReader.getRequestMapper());
35 | }
36 | }
37 |
38 | @Api
39 | public class Application {
40 | @RequestMapping
41 | public String home() {
42 | return "Hello World!";
43 | }
44 | public static void main(String[] args) {
45 | TinyApplication.run(BootAppLoaderListener.class, args);
46 | }
47 | }
48 | ```
49 | 配置`application.properties`
50 |
51 | ```
52 | tiny4j.component-scan = com.xxx.yyy
53 | tiny4j.server.contextPath = /twogoods
54 | tiny4j.server.port = 8080
55 | ```
56 | #### 打包
57 | 不造轮子,直接使用SpringBoot的Maven插件(gradle也类似)
58 |
59 | ```
60 |
61 |
62 | org.springframework.boot
63 | spring-boot-maven-plugin
64 | 1.5.2.RELEASE
65 |
66 |
67 |
68 | repackage
69 |
70 |
71 |
72 |
73 | true
74 |
75 |
76 |
77 | ```
78 | #### 单独使用
79 | 上面helloworld的代码整合了IOC,如果单独使用直接使用`SingleRestLoaderListener`
80 |
81 | ```
82 | @Api
83 | public class Application {
84 | @RequestMapping
85 | public String home() {
86 | return "Hello World!";
87 | }
88 | public static void main(String[] args) {
89 | TinyApplication.run(BootAppLoaderListener.class, args);
90 | }
91 | }
92 |
93 | ```
94 | 更多请参考`web-containerembed`测试模块。
95 | ### 传统的war形式
96 | #### 单独模式
97 | 即脱离IOC单独使用rest,所有的配置都在web.xml里
98 |
99 | ```
100 |
101 |
102 |
103 | component-scan
104 | com.tg.web.controller,com.tg.web.base
105 |
106 |
107 |
108 | com.tg.tiny4j.web.contextlistener.SingleRestLoaderListener
109 |
110 |
111 |
112 | dispatcherServlet
113 | com.tg.tiny4j.web.servlet.DispatcherServlet
114 |
115 |
116 |
117 | dispatcherServlet
118 | /
119 |
120 |
121 | ```
122 | #### 整合模式
123 | 配合IOC使用,导入core模块依赖,继承`AbstractWebContextListener`完成自己的`ContextListener`(复制下面代码即可)
124 |
125 | ```
126 | public class WebAppLoaderListener extends AbstractWebContextListener {
127 | private final WebAppControllerReader webAppControllerReader = new WebAppControllerReader();
128 |
129 | @Override
130 | public void registerHandle(HandleRegistry registry) {
131 | HandleAnnotation handle = new HandleAnnotation() {
132 | @Override
133 | public BeanDefinition handle(Class clazz) throws Exception {
134 | BaseInfo baseInfo = webAppControllerReader.read(clazz);
135 | if (Validate.isEmpty(baseInfo)) {
136 | return null;
137 | } else {
138 | return new BeanDefinition(baseInfo.getName(), baseInfo.getClassName());
139 | }
140 | }
141 | };
142 | registry.addHandle(handle);
143 | }
144 |
145 | @Override
146 | public void requestMapInitialized(ServletContextEvent servletContextEvent, WebApplicationContext applicationContext) throws Exception {
147 | webAppControllerReader.initRequestMap();
148 | webAppControllerReader.setInstances(applicationContext.getBean(webAppControllerReader.getControllerName()));
149 | servletContextEvent.getServletContext().setAttribute(WebApplicationEnvironment.WEBREQUESTMAPPER, webAppControllerReader.getRequestMapper());
150 | }
151 | }
152 | ```
153 | 相应地在web.xml里配上刚刚创建的`ContextListener`就完成了rest和Ioc的整合,诸如扫描的包等配置,相应的移到application.xml
154 |
155 | ```
156 |
157 |
158 |
159 | com.xxx.WebAppLoaderListener
160 |
161 |
162 |
163 | dispatcherServlet
164 | com.tg.tiny4j.web.servlet.DispatcherServlet
165 |
166 |
167 |
168 | dispatcherServlet
169 | /
170 |
171 |
172 | ```
173 | application.xml增加一些config的配置,`Bean`以及更多的配置参见core模块
174 |
175 | ```
176 |
177 |
178 |
179 |
180 | application.properties
181 | ${tiny4j.component-scan:com.tg.web.controller}
182 |
183 |
184 | ```
185 |
186 |
187 | ### 具体使用
188 | rest提供了一些注解可以方便的使用,熟悉SpringMvc的同学一看就懂了。`@CROS`加上此注解就可跨域,可以配置请求源,方法等;`@PathVariable`,`@RequestParam`,`@RequestParam`和SpringMvc用法一样;方法返回值会转换成Json输出。
189 |
190 | ```
191 | @RequestMapping(mapUrl = "/test/{id}", method = HttpMethod.GET)
192 | @CROS(origins = "www.baidu.com", methods = {HttpMethod.GET}, maxAge = "3600")
193 | public Map modelTest(@PathVariable("id") long id, @RequestParam("name") String name, @RequestParam User user) {
194 | Map map = new HashMap<>();
195 | map.put("name", name);
196 | map.put("id", id);
197 | map.put("user", user);
198 | return map;
199 | }
200 | ```
201 | `@Interceptor`用于标识一个拦截器,order表示拦截器先后执行顺序(越小越靠前),name默认是类名首字母小写,pathPatterns配置拦截的url。此处拦截器是基于url拦截的,而rest同一个url的不同请求方法的拦截处理这个注解就无法完成。
202 | `@InterceptorSelect`配置响应方法走哪几个拦截器,不走哪几个,这种方式粒度更小,可以确保拦截器被正确执行解决上面的问题,因此**推荐**使用这种配置方法,当然也可以配合`@Interceptor`里的pathPatterns使用。
203 |
204 | ```
205 | @Interceptor(pathPatterns = {"/base/user"},order = 2)
206 | public class AInterceptor implements HandlerInterceptor{
207 | @Override
208 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response) {
209 | System.out.println("do A interceptor");
210 | return true;
211 | }
212 | }
213 |
214 | //controller里的响应方法
215 | @RequestMapping(mapUrl = "/test", method = HttpMethod.GET)
216 | @InterceptorSelect(include = {"aInterceptor"}, exclude = {"bInterceptor"})
217 | public String interceptorTest() {
218 | return "haha";
219 | }
220 | ```
221 | 异常处理也相同
222 |
223 | ```
224 | @ExceptionHandler(Exception.class)
225 | public String handleException(){
226 | return "error";
227 | }
228 |
229 | @RequestMapping(mapUrl = "/exception", method = HttpMethod.GET)
230 | public String exceptionTest() {
231 | int i = 1 / 0;
232 | return "haha";
233 | }
234 | ```
235 | 当然,如果你是配合IOC使用的,那IOC支持的都可以无所顾忌的拿来使用
236 |
237 | ```
238 | @Api("/base")
239 | public class TestController extends BaseController {
240 |
241 | @Value("${user.name:test}")
242 | private String name;
243 |
244 | @Inject
245 | private UserService userService;
246 |
247 | @RequestMapping
248 | public String index() {
249 | userService.query();
250 | return name;
251 | }
252 | }
253 | ```
254 | 更多请直接查看[例子](https://github.com/twogoods/tiny4j/tree/master/web-test)
--------------------------------------------------------------------------------
/rest/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | tiny4j
7 | com.twogoods.tiny4j
8 | 0.0.1
9 |
10 | 4.0.0
11 |
12 | rest
13 |
14 |
15 |
16 |
17 | com.twogoods.tiny4j
18 | commons
19 | 0.0.1
20 |
21 |
22 | org.eclipse.jetty
23 | jetty-server
24 | 9.4.2.v20170220
25 |
26 |
27 | org.eclipse.jetty
28 | jetty-webapp
29 | 9.4.2.v20170220
30 |
31 |
32 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/annotation/Api.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Created by twogoods on 16/11/1.
10 | */
11 | @Target({ElementType.TYPE})
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface Api {
14 | String value() default "";
15 | String name() default "";
16 | String note() default "";
17 | }
18 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/annotation/CROS.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.annotation;
2 |
3 | import com.tg.tiny4j.commons.constants.HttpMethod;
4 |
5 | import java.lang.annotation.ElementType;
6 | import java.lang.annotation.Retention;
7 | import java.lang.annotation.RetentionPolicy;
8 | import java.lang.annotation.Target;
9 |
10 | /**
11 | * Created by twogoods on 16/11/1.
12 | */
13 | @Target({ElementType.METHOD,ElementType.TYPE})
14 | @Retention(RetentionPolicy.RUNTIME)
15 | public @interface CROS {
16 | String origins() default "*";
17 | String[] methods() default {HttpMethod.GET,HttpMethod.POST,HttpMethod.PUT,HttpMethod.PATCH,HttpMethod.DELETE};
18 | String maxAge() default "3600";
19 | String headers() default "";
20 | boolean cookie() default false;
21 | }
22 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/annotation/ComponentScan.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.annotation;
2 |
3 | /**
4 | * Created by twogoods on 16/12/6.
5 | */
6 | public @interface ComponentScan {
7 | String[] value();
8 | }
9 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/annotation/ExceptionHandler.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Created by twogoods on 16/11/1.
10 | */
11 | @Target({ElementType.METHOD})
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface ExceptionHandler {
14 | Class value();
15 | }
16 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/annotation/Interceptor.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Created by twogoods on 16/11/7.
10 | */
11 | @Target({ElementType.TYPE})
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface Interceptor {
14 | String name() default "";
15 | String[] pathPatterns() default {};
16 | String[] excludePathPatterns() default {};
17 | int order() default 0;
18 | }
19 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/annotation/InterceptorExclude.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Created by twogoods on 16/11/1.
10 | */
11 | @Target({ElementType.METHOD})
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface InterceptorExclude {
14 | String[] interceptors();
15 | }
16 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/annotation/InterceptorInclude.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Created by twogoods on 16/11/1.
10 | */
11 | @Target({ElementType.METHOD})
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface InterceptorInclude {
14 | String[] interceptors();
15 | }
16 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/annotation/InterceptorSelect.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Created by twogoods on 16/12/4.
10 | */
11 | @Target({ElementType.METHOD})
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface InterceptorSelect {
14 | String[] include() default {};
15 | String[] exclude() default {};
16 | }
17 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/annotation/PathVariable.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Created by twogoods on 16/11/1.
10 | */
11 | @Target({ElementType.PARAMETER})
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface PathVariable {
14 | String value();
15 | }
16 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/annotation/RequestBody.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Created by twogoods on 16/11/1.
10 | */
11 | @Target({ElementType.PARAMETER})
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface RequestBody {
14 | }
15 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/annotation/RequestMapping.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Created by twogoods on 16/11/1.
10 | */
11 | @Target({ElementType.METHOD})
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface RequestMapping {
14 | String mapUrl() default "";
15 | String method() default "";
16 | }
17 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/annotation/RequestParam.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.annotation;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Created by twogoods on 16/12/2.
10 | */
11 | @Target({ElementType.PARAMETER})
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface RequestParam {
14 | String value() default "";
15 | }
16 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/contextlistener/SingleRestLoaderListener.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.contextlistener;
2 |
3 | import com.tg.tiny4j.commons.constants.WebApplicationEnvironment;
4 | import com.tg.tiny4j.web.reader.ConfigLoader;
5 | import com.tg.tiny4j.web.reader.WebScanedClassReader;
6 | import org.apache.commons.lang3.StringUtils;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | import javax.servlet.ServletContextEvent;
11 | import javax.servlet.ServletContextListener;
12 |
13 | /**
14 | * Created by twogoods on 16/11/2.
15 | */
16 | public class SingleRestLoaderListener implements ServletContextListener {
17 | private static Logger log = LoggerFactory.getLogger(SingleRestLoaderListener.class);
18 |
19 | @Override
20 | public void contextInitialized(ServletContextEvent servletContextEvent) {
21 | //TODO 去掉Web.xml下的包配置,使用注解?
22 | log.info("contextInit...");
23 | try {
24 | String packages = ConfigLoader.loadConfig().getComponentscan();
25 | if (StringUtils.isEmpty(packages)) {
26 | packages = servletContextEvent.getServletContext().getInitParameter("component-scan");
27 | }
28 | log.debug("auto package: {}", packages);
29 | WebScanedClassReader webScanedClassReader = new WebScanedClassReader();
30 | webScanedClassReader.loadClass(packages);
31 | webScanedClassReader.initRequestMap();
32 | webScanedClassReader.instance4SingleMode();
33 | servletContextEvent.getServletContext().setAttribute(WebApplicationEnvironment.RUN_MODE, WebApplicationEnvironment.SINGLE_MODE);
34 | servletContextEvent.getServletContext().setAttribute(WebApplicationEnvironment.WEBREQUESTMAPPER, webScanedClassReader.getRequestMapper());
35 | } catch (Exception e) {
36 | log.error("start rest failed", e);
37 | }
38 | }
39 |
40 | @Override
41 | public void contextDestroyed(ServletContextEvent servletContextEvent) {
42 | log.info("SingleRestLoaderListener destroyed...");
43 | }
44 | }
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/exception/ConfigurationException.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.exception;
2 |
3 | /**
4 | * Description:
5 | *
6 | * @author twogoods
7 | * @version 0.1
8 | * @since 2017-03-13
9 | */
10 | public class ConfigurationException extends Exception{
11 | public ConfigurationException(String message) {
12 | super(message);
13 | }
14 |
15 | public ConfigurationException(String message, Throwable cause) {
16 | super(message, cause);
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/exception/ExceptionHandleException.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.exception;
2 |
3 | /**
4 | * Created by twogoods on 16/11/8.
5 | */
6 | public class ExceptionHandleException extends Exception{
7 |
8 | public ExceptionHandleException(String message) {
9 | super(message);
10 | }
11 |
12 | public ExceptionHandleException(String message, Throwable cause) {
13 | super(message, cause);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/exception/InterceptorDuplicatedException.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.exception;
2 |
3 | /**
4 | * Created by twogoods on 16/11/9.
5 | */
6 | public class InterceptorDuplicatedException extends Exception{
7 | public InterceptorDuplicatedException(String message) {
8 | super(message);
9 | }
10 |
11 | public InterceptorDuplicatedException(String message, Throwable cause) {
12 | super(message, cause);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/exception/UrlDuplicatedException.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.exception;
2 |
3 |
4 | /**
5 | * Created by twogoods on 16/12/3.
6 | */
7 | public class UrlDuplicatedException extends Exception{
8 | public UrlDuplicatedException(String message) {
9 | super(message);
10 | }
11 |
12 | public UrlDuplicatedException(String message, Throwable cause) {
13 | super(message, cause);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/handle/RequestHandleMapping.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.handle;
2 |
3 | import javax.servlet.http.HttpServletRequest;
4 | import javax.servlet.http.HttpServletResponse;
5 |
6 | /**
7 | * Created by twogoods on 16/11/10.
8 | */
9 | public class RequestHandleMapping {
10 |
11 | public static void handle(HttpServletRequest req, HttpServletResponse resp){
12 |
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/integration/WebAppControllerReader.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.integration;
2 |
3 | import com.tg.tiny4j.web.metadata.ControllerInfo;
4 | import com.tg.tiny4j.web.metadata.InterceptorInfo;
5 | import com.tg.tiny4j.web.reader.AbstractClassReader;
6 |
7 | import java.util.ArrayList;
8 | import java.util.List;
9 | import java.util.Map;
10 |
11 | /**
12 | * Created by twogoods on 16/11/2.
13 | */
14 | public class WebAppControllerReader extends AbstractClassReader {
15 |
16 | public List getControllerName() {
17 | List objNamesList=new ArrayList<>();
18 | Map controllerInfoMap = getRequestMapper().getApis();
19 | for (String key : controllerInfoMap.keySet()) {
20 | objNamesList.add(controllerInfoMap.get(key).getName());
21 | }
22 | for (InterceptorInfo interceptor : getRequestMapper().getInterceptorList()) {
23 | objNamesList.add(interceptor.getName());
24 | }
25 | return objNamesList;
26 | }
27 |
28 | public void setInstances(Map instances){
29 | Map controllerInfoMap = getRequestMapper().getApis();
30 | for (String key : controllerInfoMap.keySet()) {
31 | controllerInfoMap.get(key).setObject(instances.get(key));
32 | }
33 | for (InterceptorInfo interceptor : getRequestMapper().getInterceptorList()) {
34 | interceptor.setObj(instances.get(interceptor.getName()));
35 | }
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/interceptor/HandlerInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.interceptor;
2 |
3 | import javax.servlet.http.HttpServletRequest;
4 | import javax.servlet.http.HttpServletResponse;
5 |
6 | /**
7 | * Created by twogoods on 16/11/7.
8 | */
9 | public interface HandlerInterceptor {
10 | boolean preHandle(HttpServletRequest request, HttpServletResponse response);
11 | }
12 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/jettyembed/Configuration.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.jettyembed;
2 |
3 | /**
4 | * Description:
5 | *
6 | * @author twogoods
7 | * @version 0.1
8 | * @since 2017-03-31
9 | */
10 | public class Configuration {
11 | private String componentscan;
12 | private String contextPath = "twogoods";
13 | private int port = 8080;
14 |
15 | public String getComponentscan() {
16 | return componentscan;
17 | }
18 |
19 | public void setComponentscan(String componentscan) {
20 | this.componentscan = componentscan;
21 | }
22 |
23 | public String getContextPath() {
24 | return contextPath;
25 | }
26 |
27 | public void setContextPath(String contextPath) {
28 | this.contextPath = contextPath;
29 | }
30 |
31 | public int getPort() {
32 | return port;
33 | }
34 |
35 | public void setPort(int port) {
36 | this.port = port;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/jettyembed/TinyApplication.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.jettyembed;
2 |
3 | import com.tg.tiny4j.web.reader.ConfigLoader;
4 | import com.tg.tiny4j.web.servlet.DispatcherServlet;
5 | import org.eclipse.jetty.server.Server;
6 | import org.eclipse.jetty.servlet.ServletContextHandler;
7 |
8 | import java.util.EventListener;
9 |
10 | /**
11 | * Description:
12 | *
13 | * @author twogoods
14 | * @version 0.1
15 | * @since 2017-03-31
16 | */
17 | public class TinyApplication {
18 | public static void run(Class extends EventListener> listener, String[] args) {
19 | try {
20 | Configuration configuration = ConfigLoader.loadConfig();
21 | Server server = new Server(configuration.getPort());
22 | ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
23 | context.setContextPath(configuration.getContextPath());
24 | context.addEventListener(listener.newInstance());
25 | context.addServlet(DispatcherServlet.class, "/*");
26 | server.setHandler(context);
27 | server.start();
28 | server.join();
29 | } catch (Exception e) {
30 | throw new RuntimeException(e);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/metadata/BaseInfo.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.metadata;
2 |
3 | /**
4 | * Created by twogoods on 16/11/9.
5 | */
6 | public class BaseInfo {
7 | protected String name;
8 | protected String className;
9 | protected Class clazz;
10 |
11 | public String getName() {
12 | return name;
13 | }
14 |
15 | public void setName(String name) {
16 | this.name = name;
17 | }
18 |
19 | public String getClassName() {
20 | return className;
21 | }
22 |
23 | public void setClassName(String className) {
24 | this.className = className;
25 | }
26 |
27 | public Class getClazz() {
28 | return clazz;
29 | }
30 |
31 | public void setClazz(Class clazz) {
32 | this.clazz = clazz;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/metadata/ControllerInfo.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.metadata;
2 |
3 | /**
4 | * Created by twogoods on 16/11/2.
5 | */
6 | public class ControllerInfo extends BaseInfo{
7 | private Object object;
8 |
9 | public Object getObject() {
10 | return object;
11 | }
12 |
13 | public void setObject(Object object) {
14 | this.object = object;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/metadata/CrosInfo.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.metadata;
2 |
3 | /**
4 | * Created by twogoods on 16/12/3.
5 | */
6 | public class CrosInfo {
7 | private String origins;
8 | private String[] methods;
9 | private String maxAge;
10 | private String headers;
11 | private boolean cookie;
12 |
13 | public CrosInfo() {
14 | }
15 |
16 | public CrosInfo(String origins, String[] methods, String maxAge, String headers, boolean cookie) {
17 | this.origins = origins;
18 | this.methods = methods;
19 | this.maxAge = maxAge;
20 | this.headers = headers;
21 | this.cookie = cookie;
22 | }
23 |
24 | public String getOrigins() {
25 | return origins;
26 | }
27 |
28 | public void setOrigins(String origins) {
29 | this.origins = origins;
30 | }
31 |
32 | public String[] getMethods() {
33 | return methods;
34 | }
35 |
36 | public void setMethods(String[] methods) {
37 | this.methods = methods;
38 | }
39 |
40 | public String getMaxAge() {
41 | return maxAge;
42 | }
43 |
44 | public void setMaxAge(String maxAge) {
45 | this.maxAge = maxAge;
46 | }
47 |
48 | public String getHeaders() {
49 | return headers;
50 | }
51 |
52 | public void setHeaders(String headers) {
53 | this.headers = headers;
54 | }
55 |
56 | public boolean isCookie() {
57 | return cookie;
58 | }
59 |
60 | public void setCookie(boolean cookie) {
61 | this.cookie = cookie;
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/metadata/ExceptionHandleInfo.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.metadata;
2 |
3 |
4 | import java.lang.reflect.Method;
5 |
6 | /**
7 | * Created by twogoods on 16/11/8.
8 | */
9 | public class ExceptionHandleInfo {
10 | private String beanName;
11 | private String exceptionName;
12 | private Method method;
13 |
14 | public ExceptionHandleInfo() {
15 | }
16 |
17 | public ExceptionHandleInfo(String beanName, String exceptionName, Method method) {
18 | this.beanName = beanName;
19 | this.exceptionName = exceptionName;
20 | this.method = method;
21 | }
22 |
23 | public String getExceptionName() {
24 | return exceptionName;
25 | }
26 |
27 | public void setExceptionName(String exceptionName) {
28 | this.exceptionName = exceptionName;
29 | }
30 |
31 | public Method getMethod() {
32 | return method;
33 | }
34 |
35 | public void setMethod(Method method) {
36 | this.method = method;
37 | }
38 |
39 | public String getBeanName() {
40 | return beanName;
41 | }
42 |
43 | public void setBeanName(String beanName) {
44 | this.beanName = beanName;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/metadata/InterceptorInfo.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.metadata;
2 |
3 | /**
4 | * Created by twogoods on 16/11/7.
5 | */
6 | public class InterceptorInfo extends BaseInfo{
7 | private Object obj;
8 | private String[] pathPatterns;
9 | private String[] excludePathPatterns;
10 | int order;
11 |
12 |
13 | public String[] getPathPatterns() {
14 | return pathPatterns;
15 | }
16 |
17 | public void setPathPatterns(String[] pathPatterns) {
18 | this.pathPatterns = pathPatterns;
19 | }
20 |
21 | public String[] getExcludePathPatterns() {
22 | return excludePathPatterns;
23 | }
24 |
25 | public void setExcludePathPatterns(String[] excludePathPatterns) {
26 | this.excludePathPatterns = excludePathPatterns;
27 | }
28 |
29 | public int getOrder() {
30 | return order;
31 | }
32 |
33 | public void setOrder(int order) {
34 | this.order = order;
35 | }
36 |
37 | public Object getObj() {
38 | return obj;
39 | }
40 |
41 | public void setObj(Object obj) {
42 | this.obj = obj;
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/metadata/RequestHandleInfo.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.metadata;
2 |
3 | import java.lang.reflect.Method;
4 | import java.util.*;
5 |
6 | /**
7 | * Created by twogoods on 16/11/2.
8 | */
9 | public class RequestHandleInfo {
10 | /**
11 | * url,controller对象,方法,请求方法,拦截器信息
12 | * url对应一个请求方法
13 | * 在一个map,存controller对象,或者ioc里拿
14 | */
15 | private String methodName;
16 | private Method method;
17 | private String className;
18 | private String beanName;
19 | private Object instance;
20 | private String requestUrl;
21 | private String requestmethod;
22 | private UrlPraseInfo urlPraseInfo;
23 | private CrosInfo cros;
24 | private List includeInterceptors = new ArrayList<>();
25 | private List excludeInterceptors = new ArrayList<>();
26 | private Map doInterceptors = new HashMap<>();
27 |
28 | public String getMethodName() {
29 | return methodName;
30 | }
31 |
32 | public void setMethodName(String methodName) {
33 | this.methodName = methodName;
34 | }
35 |
36 | public Method getMethod() {
37 | return method;
38 | }
39 |
40 | public void setMethod(Method method) {
41 | this.method = method;
42 | }
43 |
44 | public String getClassName() {
45 | return className;
46 | }
47 |
48 | public void setClassName(String className) {
49 | this.className = className;
50 | }
51 |
52 | public String getBeanName() {
53 | return beanName;
54 | }
55 |
56 | public void setBeanName(String beanName) {
57 | this.beanName = beanName;
58 | }
59 |
60 | public Object getInstance() {
61 | return instance;
62 | }
63 |
64 | public void setInstance(Object instance) {
65 | this.instance = instance;
66 | }
67 |
68 | public String getRequestUrl() {
69 | return requestUrl;
70 | }
71 |
72 | public void setRequestUrl(String requestUrl) {
73 | this.requestUrl = requestUrl;
74 | }
75 |
76 | public String getRequestmethod() {
77 | return requestmethod;
78 | }
79 |
80 | public void setRequestmethod(String requestmethod) {
81 | this.requestmethod = requestmethod;
82 | }
83 |
84 | public UrlPraseInfo getUrlPraseInfo() {
85 | return urlPraseInfo;
86 | }
87 |
88 | public void setUrlPraseInfo(UrlPraseInfo urlPraseInfo) {
89 | this.urlPraseInfo = urlPraseInfo;
90 | }
91 |
92 | public CrosInfo getCros() {
93 | return cros;
94 | }
95 |
96 | public void setCros(CrosInfo cros) {
97 | this.cros = cros;
98 | }
99 |
100 | public List getIncludeInterceptors() {
101 | return includeInterceptors;
102 | }
103 |
104 | public void setIncludeInterceptors(String[] includeInterceptors) {
105 | this.includeInterceptors.addAll(Arrays.asList(includeInterceptors));
106 | }
107 |
108 | public void setExcludeInterceptors(String[] excludeInterceptors) {
109 | this.excludeInterceptors.addAll(Arrays.asList(excludeInterceptors));
110 | }
111 |
112 | public List getExcludeInterceptors() {
113 | return excludeInterceptors;
114 | }
115 |
116 | public Map getDoInterceptors() {
117 | return doInterceptors;
118 | }
119 |
120 | public void addDoInterceptors(String interceptor) {
121 | this.doInterceptors.put(interceptor, interceptor);
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/metadata/RequestMapper.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.metadata;
2 |
3 | import com.tg.tiny4j.web.exception.ExceptionHandleException;
4 | import com.tg.tiny4j.web.exception.InterceptorDuplicatedException;
5 | import com.tg.tiny4j.web.exception.UrlDuplicatedException;
6 |
7 | import java.util.*;
8 |
9 | /**
10 | * Created by twogoods on 16/11/8.
11 | */
12 | public class RequestMapper {
13 | //Controller 类信息和实例化的对象
14 | private Map apis = new HashMap<>();
15 | //拦截器信息
16 | private Map interceptors = new HashMap<>();
17 | //list的顺序就是拦截顺序
18 | private List interceptorList = new ArrayList<>();
19 | //处理请求的信息
20 | private Map requestHandleMap = new HashMap<>();
21 |
22 | private List urlPraseResult = new ArrayList<>();
23 |
24 | //异常信息
25 | private Map> exceptionHandles = new HashMap<>();
26 |
27 | public void sortInterceptorList() {
28 | Collections.sort(interceptorList, new Comparator() {
29 | @Override
30 | public int compare(InterceptorInfo o1, InterceptorInfo o2) {
31 | return o1.getOrder() - o2.getOrder();
32 | }
33 | });
34 | }
35 |
36 | public void addApis(String name, ControllerInfo controllerInfo) {
37 | this.apis.put(name, controllerInfo);
38 | }
39 |
40 | public void addInterceptorList(InterceptorInfo interceptorInfo) {
41 | this.interceptorList.add(interceptorInfo);
42 | }
43 |
44 | public void addRequestHandleMap(String url, RequestHandleInfo requestHandleInfo) throws UrlDuplicatedException {
45 | if (this.requestHandleMap.putIfAbsent(url, requestHandleInfo) != null) {
46 | throw new UrlDuplicatedException(String.format("check duplicated url : '%s'", url.replace("\\w*", "**")));
47 | }
48 | }
49 |
50 | public void addExceptionHandle(String className, ExceptionHandleInfo exceptionHandleInfo) throws ExceptionHandleException {
51 | Map map = exceptionHandles.get(className);
52 | if (map == null) {
53 | map = new HashMap<>();
54 | map.put(exceptionHandleInfo.getExceptionName(), exceptionHandleInfo);
55 | exceptionHandles.put(className, map);
56 | } else {
57 | if (map.putIfAbsent(exceptionHandleInfo.getExceptionName(), exceptionHandleInfo) != null) {
58 | throw new ExceptionHandleException(String.format("%s duplicated exceptionhandle for '%s'", className, exceptionHandleInfo.getExceptionName()));
59 | }
60 | }
61 | }
62 |
63 | public Map getApis() {
64 | return apis;
65 | }
66 |
67 | public void addInterceptors(String name, InterceptorInfo interceptor) throws InterceptorDuplicatedException {
68 | if (this.interceptors.put(name, interceptor) != null) {
69 | throw new InterceptorDuplicatedException(String.format("name '%s' is Duplicated, check interceptor '%s'", name, interceptor.getClassName()));
70 | }
71 | }
72 |
73 | public Map getInterceptors() {
74 | return interceptors;
75 | }
76 |
77 | public List getInterceptorList() {
78 | return interceptorList;
79 | }
80 |
81 | public Map getRequestHandleMap() {
82 | return requestHandleMap;
83 | }
84 |
85 | public Map> getExceptionHandles() {
86 | return exceptionHandles;
87 | }
88 |
89 | public List getUrlPraseResult() {
90 | return urlPraseResult;
91 | }
92 |
93 | public void addUrlPraseResult(String prasedUrl) throws UrlDuplicatedException {
94 | for (String s : urlPraseResult) {
95 | if (s.equals(prasedUrl)) {
96 | throw new UrlDuplicatedException(String.format("url duplicated ! two url: '%s' , '%s'", prasedUrl.replace("\\w*", "**"), s.replace("\\w*", "**")));
97 | }
98 | }
99 | urlPraseResult.add(prasedUrl);
100 | }
101 |
102 | @Override
103 | public String toString() {
104 | return "RequestMapper{" +
105 | "apis=" + apis +
106 | ", interceptors=" + interceptors +
107 | ", interceptorList=" + interceptorList +
108 | ", requestHandleMap=" + requestHandleMap +
109 | ", exceptionHandles=" + exceptionHandles +
110 | '}';
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/metadata/UrlPraseInfo.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.metadata;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Created by twogoods on 16/12/3.
7 | */
8 | public class UrlPraseInfo {
9 | private String match;
10 | private List params;
11 |
12 | public UrlPraseInfo() {
13 | }
14 |
15 | public UrlPraseInfo(String match, List params) {
16 | this.match = match;
17 | this.params = params;
18 | }
19 |
20 | public String getMatch() {
21 | return match;
22 | }
23 |
24 | public void setMatch(String match) {
25 | this.match = match;
26 | }
27 |
28 | public List getParams() {
29 | return params;
30 | }
31 |
32 | public void setParams(List params) {
33 | this.params = params;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/reader/ClassScanner.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.reader;
2 |
3 | import org.apache.commons.io.IOUtils;
4 | import org.apache.commons.lang3.StringUtils;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 |
8 | import java.io.File;
9 | import java.io.FileNotFoundException;
10 | import java.io.IOException;
11 | import java.net.JarURLConnection;
12 | import java.net.URL;
13 | import java.net.URLConnection;
14 | import java.net.URLDecoder;
15 | import java.util.Enumeration;
16 | import java.util.HashSet;
17 | import java.util.List;
18 | import java.util.Set;
19 | import java.util.jar.JarEntry;
20 | import java.util.jar.JarFile;
21 | import java.util.jar.JarInputStream;
22 |
23 | /**
24 | * Created by twogoods on 16/10/28.
25 | */
26 | public class ClassScanner {
27 | private static final Logger log = LoggerFactory.getLogger(ClassScanner.class);
28 | public static Set getClasses(String[] packages) throws Exception {
29 | Set classes = new HashSet();
30 | for (String packageName : packages) {
31 | if (StringUtils.isEmpty(packageName)) {
32 | continue;
33 | }
34 | getClassByPackage(packageName.replace(".", File.separator), classes);
35 | }
36 | return classes;
37 | }
38 |
39 | private static void getClassByPackage(String packageName, Set classes) throws Exception {
40 | Enumeration baseURLs = ClassScanner.class.getClassLoader().getResources(packageName);
41 | URL baseURL = null;
42 | while (baseURLs.hasMoreElements()) {
43 | baseURL = baseURLs.nextElement();
44 | if (baseURL != null) {
45 | log.debug("componentscan find: {}",baseURL.toString());
46 | String protocol = baseURL.getProtocol();
47 | String basePath = baseURL.getFile();
48 | if ("jar".equals(protocol)) {
49 | //实际运行中看到了这样的形式的jar目录 /BOOT-INF/classes!/com ,classes是一个目录,去掉后面的!,原因还没弄明白.
50 | basePath = basePath.replace("classes!", "classes");
51 | String[] paths = basePath.split("jar!/");
52 | if (paths.length == 2) {
53 | findFileInJar(paths[0] + "jar!/", paths[1], classes);
54 | } else if (paths.length > 2) {
55 | int index = basePath.lastIndexOf("jar!/") + "jar".length();
56 | String lastJarPath = basePath.substring(0, index);
57 | String packagepath = basePath.substring(index + "!/".length(), basePath.length());
58 | findFileInJarWithinJar(lastJarPath, packagepath, classes);
59 | }
60 | } else {
61 | getClassesInFile(basePath, packageName, classes);
62 | }
63 | }
64 | }
65 | }
66 |
67 | private static void findFileInJar(String filePath, String packagePath, Set classes) throws IOException {
68 | URL url = new URL("jar", null, 0, filePath);
69 | URLConnection con = url.openConnection();
70 | if (con instanceof JarURLConnection) {
71 | JarURLConnection result = (JarURLConnection) con;
72 | JarFile jarFile = result.getJarFile();
73 | for (final Enumeration enumJar = jarFile.entries(); enumJar.hasMoreElements(); ) {
74 | JarEntry entry = enumJar.nextElement();
75 | filterClass(entry.getName(), packagePath, classes);
76 | }
77 | jarFile.close();
78 | }
79 | }
80 |
81 | private static void findFileInJarWithinJar(String filePath, String packagePath, Set classes) throws IOException {
82 | URL url = new URL("jar", null, 0, filePath);
83 | URLConnection con = url.openConnection();
84 | if (con instanceof JarURLConnection) {
85 | JarURLConnection jarURLConnection = (JarURLConnection) con;
86 | JarInputStream jarInputStream = new JarInputStream(jarURLConnection.getInputStream());
87 | JarEntry entry;
88 | while ((entry = jarInputStream.getNextJarEntry()) != null) {
89 | filterClass(entry.getName(), packagePath, classes);
90 | }
91 | IOUtils.closeQuietly(jarInputStream);
92 | }
93 | }
94 |
95 | private static void filterClass(String filePath, String packageName, Set classes) {
96 | if (filePath.startsWith(packageName) && filePath.endsWith(".class")) {
97 | classes.add(getWholeClassName(filePath));
98 | }
99 | }
100 |
101 |
102 | public static void getClassesInFile(String filePath, String packagePath, Set classes) throws Exception {
103 | File file = new File(filePath);
104 | if (!file.exists()) {
105 | throw new FileNotFoundException("check component-scan config, file or directory not found, path is " + filePath);
106 | }
107 | for (String fileName : file.list()) {
108 | String childFilePath = filePath;
109 | if (filePath.endsWith("/")) {
110 | childFilePath = childFilePath + fileName;
111 | } else {
112 | childFilePath = childFilePath + File.separator + fileName;
113 | }
114 | if (new File(childFilePath).isDirectory()) {
115 | getClassesInFile(childFilePath, packagePath, classes);
116 | } else if (fileName.endsWith(".class")) {
117 | String className = getWholeClassName(childFilePath);
118 | classes.add(className);
119 | }
120 | }
121 | }
122 |
123 | private static String getWholeClassName(String filePath) {
124 | if (filePath.indexOf("classes/") != -1) {
125 | return filePath.substring(filePath.indexOf("classes/") + "classes/".length(),
126 | filePath.indexOf(".class")).replaceAll("/", ".");
127 | }
128 | return filePath.substring(0, filePath.indexOf(".class")).replaceAll("/", ".");
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/reader/ConfigLoader.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.reader;
2 |
3 | import com.tg.tiny4j.commons.constants.ConfigurationElement;
4 | import com.tg.tiny4j.web.exception.ConfigurationException;
5 | import com.tg.tiny4j.web.jettyembed.Configuration;
6 | import org.apache.commons.io.IOUtils;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | import java.io.InputStream;
11 | import java.util.Enumeration;
12 | import java.util.HashMap;
13 | import java.util.Map;
14 | import java.util.Properties;
15 |
16 | /**
17 | * Description:
18 | *
19 | * @author twogoods
20 | * @version 0.1
21 | * @since 2017-03-13
22 | */
23 | public class ConfigLoader {
24 | private static final Logger log = LoggerFactory.getLogger(ConfigLoader.class);
25 |
26 |
27 | private ConfigLoader() {
28 | }
29 |
30 | public static Configuration loadConfig() throws Exception {
31 | return loadConfig(ConfigurationElement.DEFAULT_CONFIG_FILE);
32 | }
33 |
34 | public static Configuration loadConfig(String name) throws Exception {
35 | Configuration configuration = new Configuration();
36 | InputStream in = ConfigLoader.class.getClassLoader().getResourceAsStream(name);
37 | if (in == null) {
38 | throw new ConfigurationException(String.format("'%s' is not exist", name));
39 | }
40 | try {
41 | Properties prop = new Properties();
42 | prop.load(in);
43 | Enumeration en = prop.propertyNames();
44 | while (en.hasMoreElements()) {
45 | String strKey = (String) en.nextElement();
46 | log.debug("get config : {} = {}", strKey, prop.getProperty(strKey));
47 | if (ConfigurationElement.COMPONENTSCAN.equals(strKey)) {
48 | configuration.setComponentscan(prop.getProperty(strKey));
49 | } else if (ConfigurationElement.SERVER_CONTEXTPATH.equals(strKey)) {
50 | configuration.setContextPath(prop.getProperty(strKey));
51 | } else if (ConfigurationElement.SERVER_PORT.equals(strKey)) {
52 | configuration.setPort(Integer.valueOf(prop.getProperty(strKey)));
53 | }
54 | }
55 | } finally {
56 | IOUtils.closeQuietly(in);
57 | }
58 | return configuration;
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/reader/Reader.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.reader;
2 |
3 | import com.tg.tiny4j.web.metadata.BaseInfo;
4 | import com.tg.tiny4j.web.metadata.ControllerInfo;
5 | import com.tg.tiny4j.web.metadata.RequestHandleInfo;
6 | import com.tg.tiny4j.web.metadata.RequestMapper;
7 |
8 | import java.util.Map;
9 |
10 | /**
11 | * Created by twogoods on 16/11/2.
12 | */
13 | public interface Reader {
14 | BaseInfo read(Class clazz) throws Exception;
15 |
16 | RequestMapper getRequestMapper();
17 | }
18 |
--------------------------------------------------------------------------------
/rest/src/main/java/com/tg/tiny4j/web/reader/WebScanedClassReader.java:
--------------------------------------------------------------------------------
1 | package com.tg.tiny4j.web.reader;
2 |
3 | import org.apache.commons.lang3.StringUtils;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 |
7 | import java.io.FileNotFoundException;
8 | import java.util.HashSet;
9 | import java.util.Set;
10 |
11 | /**
12 | * Created by twogoods on 16/11/2.
13 | */
14 | public class WebScanedClassReader extends AbstractClassReader {
15 | private static Logger log = LoggerFactory.getLogger(WebScanedClassReader.class);
16 |
17 | Set classSet = new HashSet<>();
18 |
19 | public void loadClass(String packageConfig) {
20 | if (StringUtils.isEmpty(packageConfig)) {
21 | return;
22 | }
23 | try {
24 | Set classes = ClassScanner.getClasses(packageConfig.split(","));
25 | log.debug("get class:{}", classes);
26 | loadClasses(classes);
27 | for (Class clazz : classSet) {
28 | read(clazz);
29 | }
30 | } catch (Exception e) {
31 | log.error("loadclass error:{}", e);
32 | throw new RuntimeException(e);
33 | }
34 | }
35 |
36 | private void loadClasses(Set classes) throws ClassNotFoundException {
37 | for (String className : classes) {
38 | classSet.add(Class.forName(className));
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/web-containerembed/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | tiny4j
7 | com.twogoods.tiny4j
8 | 0.0.1
9 |
10 | 4.0.0
11 |
12 | web-containerembed
13 | jar
14 |
15 |
16 |
17 | com.twogoods.tiny4j
18 | rest
19 | 0.0.1
20 |
21 |
22 | com.twogoods.tiny4j
23 | core
24 | 0.0.1
25 |
26 |
27 |
28 | org.apache.tomcat.embed
29 | tomcat-embed-core
30 | ${tomcat.version}
31 |
32 |
33 | org.apache.tomcat.embed
34 | tomcat-embed-el
35 | ${tomcat.version}
36 |
37 |
38 | org.apache.tomcat.embed
39 | tomcat-embed-jasper
40 | ${tomcat.version}
41 |
42 |
43 | org.apache.tomcat.embed
44 | tomcat-embed-websocket
45 | ${tomcat.version}
46 |
47 |
48 | org.apache.tomcat
49 | tomcat-jdbc
50 | ${tomcat.version}
51 |
52 |
53 | org.apache.tomcat
54 | tomcat-jsp-api
55 | ${tomcat.version}
56 |
57 |
58 |
59 | org.apache.logging.log4j
60 | log4j-core
61 | 2.7
62 |
63 |
64 | org.apache.logging.log4j
65 | log4j-api
66 | 2.7
67 |
68 |
69 | org.apache.logging.log4j
70 | log4j-slf4j-impl
71 | 2.8
72 |
73 |
74 | org.apache.logging.log4j
75 | log4j-jcl
76 | 2.8
77 |
78 |
79 |
80 |
81 | web-innerjttty
82 |
83 |
84 | org.springframework.boot
85 | spring-boot-maven-plugin
86 | 1.5.2.RELEASE
87 |
88 |
89 |
90 | repackage
91 |
92 |
93 |
94 |
95 | true
96 |
97 |
98 |
99 | org.apache.maven.plugins
100 | maven-surefire-plugin
101 |
102 | true
103 |
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/web-containerembed/src/main/java/com/tg/web/Application.java:
--------------------------------------------------------------------------------
1 | package com.tg.web;
2 |
3 | import com.tg.tiny4j.web.annotation.Api;
4 | import com.tg.tiny4j.web.annotation.RequestMapping;
5 | import com.tg.tiny4j.web.contextlistener.SingleRestLoaderListener;
6 | import com.tg.tiny4j.web.jettyembed.TinyApplication;
7 | import com.tg.web.contextlistener.BootAppLoaderListener;
8 |
9 | /**
10 | * Description:
11 | *
12 | * @author twogoods
13 | * @version 0.1
14 | * @since 2017-03-31
15 | */
16 | @Api
17 | public class Application {
18 | @RequestMapping
19 | public String home() {
20 | return "Hello World!";
21 | }
22 | public static void main(String[] args) {
23 | //TinyApplication.run(SingleRestLoaderListener.class, args);
24 | TinyApplication.run(BootAppLoaderListener.class, args);
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/web-containerembed/src/main/java/com/tg/web/contextlistener/BootAppLoaderListener.java:
--------------------------------------------------------------------------------
1 | package com.tg.web.contextlistener;
2 |
3 | import com.tg.tiny4j.commons.constants.WebApplicationEnvironment;
4 | import com.tg.tiny4j.commons.utils.Validate;
5 | import com.tg.tiny4j.core.ioc.beans.BeanDefinition;
6 | import com.tg.tiny4j.core.web.integration.ContextListener.AbstractBootContextListener;
7 | import com.tg.tiny4j.core.web.integration.HandleAnnotation;
8 | import com.tg.tiny4j.core.web.integration.HandleRegistry;
9 | import com.tg.tiny4j.core.web.integration.context.WebApplicationContext;
10 | import com.tg.tiny4j.web.integration.WebAppControllerReader;
11 | import com.tg.tiny4j.web.metadata.BaseInfo;
12 | import org.apache.logging.log4j.LogManager;
13 | import org.apache.logging.log4j.Logger;
14 |
15 | import javax.servlet.ServletContextEvent;
16 |
17 | /**
18 | * Description:
19 | *
20 | * @author twogoods
21 | * @version 0.1
22 | * @since 2017-03-31
23 | */
24 | public class BootAppLoaderListener extends AbstractBootContextListener {
25 | private static final Logger log = LogManager.getLogger(BootAppLoaderListener.class);
26 |
27 | private final WebAppControllerReader webAppControllerReader = new WebAppControllerReader();
28 |
29 | @Override
30 | public void registerHandle(HandleRegistry registry) {
31 | HandleAnnotation handle = new HandleAnnotation() {
32 | @Override
33 | public BeanDefinition handle(Class clazz) throws Exception {
34 | BaseInfo baseInfo = webAppControllerReader.read(clazz);
35 | if (Validate.isEmpty(baseInfo)) {
36 | return null;
37 | } else {
38 | return new BeanDefinition(baseInfo.getName(), baseInfo.getClassName());
39 | }
40 | }
41 | };
42 | registry.addHandle(handle);
43 | }
44 |
45 | @Override
46 | public void requestMapInitialized(ServletContextEvent servletContextEvent, WebApplicationContext applicationContext) throws Exception {
47 | webAppControllerReader.initRequestMap();
48 | webAppControllerReader.setInstances(applicationContext.getBeans(webAppControllerReader.getControllerName()));
49 | servletContextEvent.getServletContext().setAttribute(WebApplicationEnvironment.WEBREQUESTMAPPER, webAppControllerReader.getRequestMapper());
50 | }
51 | }
--------------------------------------------------------------------------------
/web-containerembed/src/main/java/com/tg/web/controller/AInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.tg.web.controller;
2 |
3 | import com.tg.tiny4j.core.ioc.annotation.Inject;
4 | import com.tg.tiny4j.core.ioc.annotation.Value;
5 | import com.tg.tiny4j.web.annotation.Interceptor;
6 | import com.tg.tiny4j.web.interceptor.HandlerInterceptor;
7 | import com.tg.web.service.UserService;
8 |
9 | import javax.servlet.http.HttpServletRequest;
10 | import javax.servlet.http.HttpServletResponse;
11 |
12 | /**
13 | * Created by twogoods on 16/11/9.
14 | */
15 | @Interceptor(pathPatterns = {"/base/user"},order = 2)
16 | public class AInterceptor implements HandlerInterceptor{
17 |
18 | @Value("${user.name:test}")
19 | private String name;
20 |
21 | @Inject
22 | private UserService userService;
23 |
24 | @Override
25 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response) {
26 | System.out.println("********** A interceptor ********");
27 | System.out.println(name);
28 | // userService.query();
29 | System.out.println("********** A interceptor end ********");
30 | return true;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/web-containerembed/src/main/java/com/tg/web/controller/BInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.tg.web.controller;
2 |
3 | import com.tg.tiny4j.web.annotation.Interceptor;
4 | import com.tg.tiny4j.web.interceptor.HandlerInterceptor;
5 |
6 | import javax.servlet.http.HttpServletRequest;
7 | import javax.servlet.http.HttpServletResponse;
8 |
9 | /**
10 | * Created by twogoods on 16/11/9.
11 | */
12 | @Interceptor(pathPatterns = {"/base"},excludePathPatterns = {"/base/index"},order = 1)
13 | public class BInterceptor implements HandlerInterceptor {
14 | @Override
15 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response) {
16 | System.out.println("do b interceptor");
17 | return true;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/web-containerembed/src/main/java/com/tg/web/controller/BaseController.java:
--------------------------------------------------------------------------------
1 | package com.tg.web.controller;
2 |
3 | import com.tg.tiny4j.web.annotation.ExceptionHandler;
4 |
5 | /**
6 | * Created by twogoods on 16/11/4.
7 | */
8 | public class BaseController {
9 | @ExceptionHandler(Exception.class)
10 | public String handleException(){
11 | return "error";
12 | }
13 |
14 | @ExceptionHandler(TestException.class)
15 | public String handleExc(){
16 | return "test error";
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/web-containerembed/src/main/java/com/tg/web/controller/TestController.java:
--------------------------------------------------------------------------------
1 | package com.tg.web.controller;
2 |
3 | import com.tg.tiny4j.commons.constants.HttpMethod;
4 | import com.tg.tiny4j.core.ioc.annotation.Inject;
5 | import com.tg.tiny4j.core.ioc.annotation.Value;
6 | import com.tg.tiny4j.web.annotation.*;
7 | import com.tg.web.model.User;
8 | import com.tg.web.service.UserService;
9 |
10 | import java.util.HashMap;
11 | import java.util.Map;
12 |
13 | /**
14 | * Created by twogoods on 16/12/1.
15 | */
16 | @Api("/base")
17 | public class TestController extends BaseController {
18 |
19 | @Value("${user.name:test}")
20 | private String name;
21 |
22 | @Inject
23 | private UserService userService;
24 |
25 | @RequestMapping
26 | public String index() {
27 | userService.query();
28 | return name;
29 | }
30 |
31 | @RequestMapping(mapUrl = "/test/{id}", method = HttpMethod.GET)
32 | @CROS(origins = "www.baidu.com", methods = {HttpMethod.GET}, maxAge = "3600")
33 | public String patgTest(@PathVariable("id") String id) {
34 | return id;
35 | }
36 |
37 | @RequestMapping(mapUrl = "/test", method = HttpMethod.GET)
38 | @InterceptorSelect(include = {"aInterceptor"}, exclude = {"bInterceptor"})
39 | public String interceptorTest() {
40 | return "haha";
41 | }
42 |
43 |
44 | @RequestMapping(mapUrl = "/exception", method = HttpMethod.GET)
45 | public String exceptionTest() {
46 | int i = 1 / 0;
47 | return "haha";
48 | }
49 |
50 | @RequestMapping(mapUrl = "/index")
51 | @CROS
52 | public String paramTest(@RequestParam("id") long id, @RequestParam("name") String name) {
53 | return name + "---" + id;
54 | }
55 |
56 |
57 | @RequestMapping(mapUrl = "/user")
58 | @InterceptorExclude(interceptors = {"bInterceptor"})
59 | public Map modelTest(@RequestParam("name") String name, @RequestParam User user) {
60 | Map map = new HashMap<>();
61 | map.put("name", name);
62 | map.put("user", user);
63 | return map;
64 | }
65 |
66 | @RequestMapping(mapUrl = "/json", method = HttpMethod.POST)
67 | public User modelJson(@RequestBody User user) {
68 | return user;
69 | }
70 |
71 | @RequestMapping(mapUrl = "/user/{id}", method = HttpMethod.PUT)
72 | @CROS
73 | public User insert(@PathVariable("id") long id, @RequestBody User user) {
74 | return user;
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/web-containerembed/src/main/java/com/tg/web/controller/TestException.java:
--------------------------------------------------------------------------------
1 | package com.tg.web.controller;
2 |
3 | /**
4 | * Created by twogoods on 16/12/1.
5 | */
6 | public class TestException extends RuntimeException{
7 | public TestException() {
8 | }
9 |
10 | public TestException(String message) {
11 | super(message);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/web-containerembed/src/main/java/com/tg/web/controller/TestServlet.java:
--------------------------------------------------------------------------------
1 | package com.tg.web.controller;
2 |
3 | import javax.servlet.ServletException;
4 | import javax.servlet.annotation.WebServlet;
5 | import javax.servlet.http.HttpServlet;
6 | import javax.servlet.http.HttpServletRequest;
7 | import javax.servlet.http.HttpServletResponse;
8 | import java.io.IOException;
9 |
10 | /**
11 | * Created by twogoods on 16/12/6.
12 | */
13 | @WebServlet(name = "test",urlPatterns = {"/test"})
14 | public class TestServlet extends HttpServlet{
15 |
16 | @Override
17 | protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
18 |
19 | System.out.println("get in ...");
20 | resp.setStatus(200);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/web-containerembed/src/main/java/com/tg/web/dao/UserDao.java:
--------------------------------------------------------------------------------
1 | package com.tg.web.dao;
2 |
3 | import com.tg.tiny4j.core.ioc.annotation.Component;
4 |
5 | /**
6 | * Created by twogoods on 16/11/1.
7 | */
8 | @Component
9 | public class UserDao {
10 |
11 | public void query(){
12 | System.out.println("execute sql....");
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/web-containerembed/src/main/java/com/tg/web/model/User.java:
--------------------------------------------------------------------------------
1 | package com.tg.web.model;
2 |
3 | /**
4 | * Created by twogoods on 16/11/7.
5 | */
6 | public class User {
7 | private String name;
8 | private int age;
9 |
10 | public String getName() {
11 | return name;
12 | }
13 |
14 | public void setName(String name) {
15 | this.name = name;
16 | }
17 |
18 | public int getAge() {
19 | return age;
20 | }
21 |
22 | public void setAge(int age) {
23 | this.age = age;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/web-containerembed/src/main/java/com/tg/web/service/UserService.java:
--------------------------------------------------------------------------------
1 | package com.tg.web.service;
2 |
3 | import com.tg.tiny4j.core.ioc.annotation.Component;
4 | import com.tg.tiny4j.core.ioc.annotation.Inject;
5 | import com.tg.web.dao.UserDao;
6 |
7 | /**
8 | * Created by twogoods on 16/11/1.
9 | */
10 | @Component
11 | public class UserService {
12 |
13 | @Inject
14 | private UserDao userDao;
15 |
16 |
17 | public void query(){
18 | userDao.query();
19 | }
20 |
21 | public void setUserDao(UserDao userDao) {
22 | this.userDao = userDao;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/web-containerembed/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | tiny4j.component-scan = com.tg.web
2 | tiny4j.server.contextPath = /twogoods
3 | tiny4j.server.port = 8080
--------------------------------------------------------------------------------
/web-containerembed/src/main/resources/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/web-containerembed/src/test/java/com/tg/embed/JetttyTest.java:
--------------------------------------------------------------------------------
1 | package com.tg.embed;
2 |
3 | import com.tg.tiny4j.web.contextlistener.SingleRestLoaderListener;
4 | import com.tg.tiny4j.web.servlet.DispatcherServlet;
5 | import org.eclipse.jetty.server.Request;
6 | import org.eclipse.jetty.server.Server;
7 | import org.eclipse.jetty.server.handler.AbstractHandler;
8 | import org.eclipse.jetty.servlet.ServletContextHandler;
9 | import org.junit.Test;
10 |
11 | import javax.servlet.ServletException;
12 | import javax.servlet.http.HttpServlet;
13 | import javax.servlet.http.HttpServletRequest;
14 | import javax.servlet.http.HttpServletResponse;
15 | import java.io.IOException;
16 | import java.io.PrintWriter;
17 |
18 | /**
19 | * Description:
20 | *
21 | * @author twogoods
22 | * @version 0.1
23 | * @since 2017-03-31
24 | */
25 | public class JetttyTest {
26 | @Test
27 | public void test() throws Exception {
28 | //http://www.eclipse.org/jetty/documentation/9.4.x/embedding-jetty.html
29 | Server server = new Server(8080);
30 | ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
31 | context.setContextPath("/twogoods");
32 | context.addEventListener(new SingleRestLoaderListener());
33 | context.addServlet(DispatcherServlet.class, "/*");
34 | server.setHandler(context);
35 | server.start();
36 | server.join();
37 | }
38 |
39 |
40 | public static class HelloServlet extends HttpServlet {
41 | @Override
42 | public void init() throws ServletException {
43 | System.out.println("HelloServlet init...");
44 | }
45 |
46 | @Override
47 | protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
48 | response.setContentType("text/html");
49 | response.setStatus(HttpServletResponse.SC_OK);
50 | response.getWriter().println("Hello from HelloServlet
");
51 | }
52 | }
53 |
54 | public static class DefaultServlet extends HttpServlet {
55 | @Override
56 | protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
57 | response.setContentType("text/html");
58 | response.setStatus(HttpServletResponse.SC_OK);
59 | response.getWriter().println("default
");
60 | }
61 | }
62 |
63 | public static class HelloHandler extends AbstractHandler {
64 | public void handle(String target,
65 | Request baseRequest,
66 | HttpServletRequest request,
67 | HttpServletResponse response) throws IOException,
68 | ServletException {
69 | response.setContentType("text/html; charset=utf-8");
70 | response.setStatus(HttpServletResponse.SC_NOT_FOUND);
71 | PrintWriter out = response.getWriter();
72 | out.println("" + 404 + "
");
73 | baseRequest.setHandled(true);
74 | }
75 | }
76 | }
--------------------------------------------------------------------------------
/web-containerembed/src/test/java/com/tg/embed/TomcatTest.java:
--------------------------------------------------------------------------------
1 | package com.tg.embed;
2 |
3 | import org.apache.catalina.WebResourceRoot;
4 | import org.apache.catalina.core.StandardContext;
5 | import org.apache.catalina.startup.Tomcat;
6 | import org.apache.catalina.webresources.DirResourceSet;
7 | import org.apache.catalina.webresources.StandardRoot;
8 |
9 | import java.io.File;
10 |
11 | /**
12 | * Description:
13 | *
14 | * @author twogoods
15 | * @version 0.1
16 | * @since 2017-03-31
17 | */
18 | public class TomcatTest {
19 |
20 | //http://blog.csdn.net/hengyunabc/article/details/50120001
21 | public static void test(String[] args) throws Exception {
22 | String webappDirLocation = "web-test/src/main/webapp/";
23 | Tomcat tomcat = new Tomcat();
24 |
25 | //The port that we should run on can be set into an environment variable
26 | //Look for that variable and default to 8080 if it isn't there.
27 | String webPort = System.getenv("PORT");
28 | if (webPort == null || webPort.isEmpty()) {
29 | webPort = "8080";
30 | }
31 | tomcat.setPort(Integer.valueOf(webPort));
32 | StandardContext ctx = (StandardContext) tomcat.addWebapp("/", new File(webappDirLocation).getAbsolutePath());
33 | System.out.println("configuring app with basedir: " + new File(webappDirLocation).getAbsolutePath());
34 |
35 | // Declare an alternative location for your "WEB-INF/classes" dir
36 | // Servlet 3.0 annotation will work
37 | File additionWebInfClasses = new File("web-test/target/classes");
38 | WebResourceRoot resources = new StandardRoot(ctx);
39 | resources.addPreResources(new DirResourceSet(resources, "/WEB-INF/classes",
40 | additionWebInfClasses.getAbsolutePath(), "/"));
41 | ctx.setResources(resources);
42 |
43 | tomcat.start();
44 | tomcat.getServer().await();
45 | }
46 |
47 | }
--------------------------------------------------------------------------------
/web-test/pom.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 | tiny4j
5 | com.twogoods.tiny4j
6 | 0.0.1
7 |
8 | 4.0.0
9 | web-test
10 | war
11 | web-test Maven Webapp
12 | http://maven.apache.org
13 |
14 |
15 | com.twogoods.tiny4j
16 | rest
17 | 0.0.1
18 |
19 |
20 | com.twogoods.tiny4j
21 | core
22 | 0.0.1
23 |
24 |
25 |
26 | org.eclipse.jetty
27 | jetty-server
28 | 9.4.2.v20170220
29 |
30 |
31 | org.eclipse.jetty
32 | jetty-webapp
33 | 9.4.2.v20170220
34 |
35 |
36 |
37 | org.apache.logging.log4j
38 | log4j-core
39 | 2.7
40 |
41 |
42 | org.apache.logging.log4j
43 | log4j-web
44 | 2.7
45 |
46 |
47 | org.apache.logging.log4j
48 | log4j-api
49 | 2.7
50 |
51 |
52 | org.apache.logging.log4j
53 | log4j-slf4j-impl
54 | 2.8
55 |
56 |
57 | org.apache.logging.log4j
58 | log4j-jcl
59 | 2.8
60 |
61 |
62 | junit
63 | junit
64 | 3.8.1
65 | test
66 |
67 |
68 |
69 |
70 | web-test
71 |
72 |
73 |
--------------------------------------------------------------------------------
/web-test/src/main/java/com/tg/web/contextlistener/WebAppLoaderListener.java:
--------------------------------------------------------------------------------
1 | package com.tg.web.contextlistener;
2 |
3 | import com.tg.tiny4j.commons.constants.WebApplicationEnvironment;
4 | import com.tg.tiny4j.commons.utils.Validate;
5 | import com.tg.tiny4j.core.ioc.beans.BeanDefinition;
6 | import com.tg.tiny4j.core.web.integration.ContextListener.AbstractWebContextListener;
7 | import com.tg.tiny4j.core.web.integration.HandleAnnotation;
8 | import com.tg.tiny4j.core.web.integration.HandleRegistry;
9 | import com.tg.tiny4j.core.web.integration.context.WebApplicationContext;
10 | import com.tg.tiny4j.web.integration.WebAppControllerReader;
11 | import com.tg.tiny4j.web.metadata.BaseInfo;
12 | import org.slf4j.Logger;
13 | import org.slf4j.LoggerFactory;
14 |
15 |
16 | import javax.servlet.ServletContextEvent;
17 |
18 | /**
19 | * Created by twogoods on 16/11/2.
20 | */
21 | public class WebAppLoaderListener extends AbstractWebContextListener {
22 | private static final Logger log = LoggerFactory.getLogger(WebAppLoaderListener.class);
23 |
24 | private final WebAppControllerReader webAppControllerReader = new WebAppControllerReader();
25 |
26 | @Override
27 | public void registerHandle(HandleRegistry registry) {
28 | HandleAnnotation handle = new HandleAnnotation() {
29 | @Override
30 | public BeanDefinition handle(Class clazz) throws Exception {
31 | BaseInfo baseInfo = webAppControllerReader.read(clazz);
32 | if (Validate.isEmpty(baseInfo)) {
33 | return null;
34 | } else {
35 | return new BeanDefinition(baseInfo.getName(), baseInfo.getClassName());
36 | }
37 | }
38 | };
39 | registry.addHandle(handle);
40 | }
41 |
42 | @Override
43 | public void requestMapInitialized(ServletContextEvent servletContextEvent, WebApplicationContext applicationContext) throws Exception {
44 | webAppControllerReader.initRequestMap();
45 | webAppControllerReader.setInstances(applicationContext.getBeans(webAppControllerReader.getControllerName()));
46 | servletContextEvent.getServletContext().setAttribute(WebApplicationEnvironment.WEBREQUESTMAPPER, webAppControllerReader.getRequestMapper());
47 | }
48 | }
--------------------------------------------------------------------------------
/web-test/src/main/java/com/tg/web/controller/AInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.tg.web.controller;
2 |
3 | import com.tg.tiny4j.core.ioc.annotation.Inject;
4 | import com.tg.tiny4j.core.ioc.annotation.Value;
5 | import com.tg.tiny4j.web.annotation.Interceptor;
6 | import com.tg.tiny4j.web.interceptor.HandlerInterceptor;
7 | import com.tg.web.service.UserService;
8 |
9 | import javax.servlet.http.HttpServletRequest;
10 | import javax.servlet.http.HttpServletResponse;
11 |
12 | /**
13 | * Created by twogoods on 16/11/9.
14 | */
15 | @Interceptor(pathPatterns = {"/base/user"},order = 2)
16 | public class AInterceptor implements HandlerInterceptor{
17 |
18 | @Value("${user.name:test}")
19 | private String name;
20 |
21 | @Inject
22 | private UserService userService;
23 |
24 | @Override
25 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response) {
26 | System.out.println("********** A interceptor ********");
27 | System.out.println(name);
28 | // userService.query();
29 | System.out.println("********** A interceptor end ********");
30 | return true;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/web-test/src/main/java/com/tg/web/controller/BInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.tg.web.controller;
2 |
3 | import com.tg.tiny4j.web.annotation.Interceptor;
4 | import com.tg.tiny4j.web.interceptor.HandlerInterceptor;
5 |
6 | import javax.servlet.http.HttpServletRequest;
7 | import javax.servlet.http.HttpServletResponse;
8 |
9 | /**
10 | * Created by twogoods on 16/11/9.
11 | */
12 | @Interceptor(pathPatterns = {"/base"},excludePathPatterns = {"/base/index"},order = 1)
13 | public class BInterceptor implements HandlerInterceptor {
14 | @Override
15 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response) {
16 | System.out.println("do b interceptor");
17 | return true;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/web-test/src/main/java/com/tg/web/controller/BaseController.java:
--------------------------------------------------------------------------------
1 | package com.tg.web.controller;
2 |
3 | import com.tg.tiny4j.web.annotation.*;
4 |
5 | /**
6 | * Created by twogoods on 16/11/4.
7 | */
8 | public class BaseController {
9 | @ExceptionHandler(Exception.class)
10 | public String handleException(){
11 | return "error";
12 | }
13 |
14 | @ExceptionHandler(TestException.class)
15 | public String handleExc(){
16 | return "test error";
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/web-test/src/main/java/com/tg/web/controller/TestController.java:
--------------------------------------------------------------------------------
1 | package com.tg.web.controller;
2 |
3 | import com.tg.tiny4j.commons.constants.HttpMethod;
4 | import com.tg.tiny4j.core.ioc.annotation.Inject;
5 | import com.tg.tiny4j.core.ioc.annotation.Value;
6 | import com.tg.tiny4j.web.annotation.*;
7 | import com.tg.web.model.User;
8 | import com.tg.web.service.UserService;
9 |
10 | import java.util.HashMap;
11 | import java.util.Map;
12 |
13 | /**
14 | * Created by twogoods on 16/12/1.
15 | */
16 | @Api("/base")
17 | public class TestController extends BaseController {
18 |
19 | @Value("${user.name:test}")
20 | private String name;
21 |
22 | @Inject
23 | private UserService userService;
24 |
25 | @RequestMapping
26 | public String index() {
27 | userService.query();
28 | return name;
29 | }
30 |
31 | @RequestMapping(mapUrl = "/test/{id}", method = HttpMethod.GET)
32 | @CROS(origins = "www.baidu.com", methods = {HttpMethod.GET}, maxAge = "3600")
33 | public String patgTest(@PathVariable("id") String id) {
34 | return id;
35 | }
36 |
37 | @RequestMapping(mapUrl = "/test", method = HttpMethod.GET)
38 | @InterceptorSelect(include = {"aInterceptor"}, exclude = {"bInterceptor"})
39 | public String interceptorTest() {
40 | return "haha";
41 | }
42 |
43 |
44 | @RequestMapping(mapUrl = "/exception", method = HttpMethod.GET)
45 | public String exceptionTest() {
46 | int i = 1 / 0;
47 | return "haha";
48 | }
49 |
50 | @RequestMapping(mapUrl = "/index")
51 | @CROS
52 | public String paramTest(@RequestParam("id") long id, @RequestParam("name") String name) {
53 | return name + "---" + id;
54 | }
55 |
56 |
57 | @RequestMapping(mapUrl = "/user")
58 | @InterceptorExclude(interceptors = {"bInterceptor"})
59 | public Map modelTest(@RequestParam("name") String name, @RequestParam User user) {
60 | Map map = new HashMap<>();
61 | map.put("name", name);
62 | map.put("user", user);
63 | return map;
64 | }
65 |
66 | @RequestMapping(mapUrl = "/json", method = HttpMethod.POST)
67 | public User modelJson(@RequestBody User user) {
68 | return user;
69 | }
70 |
71 | @RequestMapping(mapUrl = "/user/{id}", method = HttpMethod.PUT)
72 | @CROS
73 | public User insert(@PathVariable("id") long id, @RequestBody User user) {
74 | return user;
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/web-test/src/main/java/com/tg/web/controller/TestException.java:
--------------------------------------------------------------------------------
1 | package com.tg.web.controller;
2 |
3 | /**
4 | * Created by twogoods on 16/12/1.
5 | */
6 | public class TestException extends RuntimeException{
7 | public TestException() {
8 | }
9 |
10 | public TestException(String message) {
11 | super(message);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/web-test/src/main/java/com/tg/web/controller/TestServlet.java:
--------------------------------------------------------------------------------
1 | package com.tg.web.controller;
2 |
3 | import javax.servlet.ServletException;
4 | import javax.servlet.annotation.WebServlet;
5 | import javax.servlet.http.HttpServlet;
6 | import javax.servlet.http.HttpServletRequest;
7 | import javax.servlet.http.HttpServletResponse;
8 | import java.io.IOException;
9 |
10 | /**
11 | * Created by twogoods on 16/12/6.
12 | */
13 | @WebServlet(name = "test",urlPatterns = {"/test"})
14 | public class TestServlet extends HttpServlet{
15 |
16 | @Override
17 | protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
18 |
19 | System.out.println("get in ...");
20 | resp.setStatus(200);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/web-test/src/main/java/com/tg/web/dao/UserDao.java:
--------------------------------------------------------------------------------
1 | package com.tg.web.dao;
2 |
3 | import com.tg.tiny4j.core.ioc.annotation.Component;
4 |
5 | /**
6 | * Created by twogoods on 16/11/1.
7 | */
8 | @Component
9 | public class UserDao {
10 |
11 | public void query(){
12 | System.out.println("execute sql....");
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/web-test/src/main/java/com/tg/web/model/User.java:
--------------------------------------------------------------------------------
1 | package com.tg.web.model;
2 |
3 | /**
4 | * Created by twogoods on 16/11/7.
5 | */
6 | public class User {
7 | private String name;
8 | private int age;
9 |
10 | public String getName() {
11 | return name;
12 | }
13 |
14 | public void setName(String name) {
15 | this.name = name;
16 | }
17 |
18 | public int getAge() {
19 | return age;
20 | }
21 |
22 | public void setAge(int age) {
23 | this.age = age;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/web-test/src/main/java/com/tg/web/service/UserService.java:
--------------------------------------------------------------------------------
1 | package com.tg.web.service;
2 |
3 | import com.tg.tiny4j.core.ioc.annotation.Component;
4 | import com.tg.tiny4j.core.ioc.annotation.Inject;
5 | import com.tg.web.dao.UserDao;
6 |
7 | /**
8 | * Created by twogoods on 16/11/1.
9 | */
10 | @Component
11 | public class UserService {
12 |
13 | @Inject
14 | private UserDao userDao;
15 |
16 |
17 | public void query(){
18 | userDao.query();
19 | }
20 |
21 | public void setUserDao(UserDao userDao) {
22 | this.userDao = userDao;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/web-test/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | tiny4j.component-scan = com.tg.web
2 | tiny4j.server.contextPath = /admin
3 | tiny4j.server.port = 8088
4 | user.name=twogoods
5 | user.pass=twogoods
--------------------------------------------------------------------------------
/web-test/src/main/resources/application.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | application.properties
5 | ${tiny4j.component-scan:com.tg.web.controller}
6 |
7 |
--------------------------------------------------------------------------------
/web-test/src/main/resources/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/web-test/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 | Archetype Created Web Application
6 |
7 |
8 | component-scan
9 | com.tg.web
10 |
11 |
12 |
13 | com.tg.web.contextlistener.WebAppLoaderListener
14 |
15 |
16 |
17 |
18 | dispatcherServlet
19 | com.tg.tiny4j.web.servlet.DispatcherServlet
20 |
21 |
22 |
23 | dispatcherServlet
24 | /
25 |
26 |
27 |
--------------------------------------------------------------------------------
/web-test/src/main/webapp/index.jsp:
--------------------------------------------------------------------------------
1 |
2 |
3 | Hello World! twogoods
4 |
5 |
6 |
--------------------------------------------------------------------------------