`
yfyh87
  • 浏览: 35539 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

一个类的简单SPRING

阅读更多
你是否常编一些小工具,做一些小东西?
在你扩展维护的时候,是不是觉得实例传递越来越复杂?
你经常改变想法,但小东西不停重构开始耽误你越来越多的时间?
你想到了用spring,但又不想对于一个简单的小东西,引入一个相对小重的框架,让你的小程序加载时都需要卡一下?


哈,试一试用下simpleFactory,是否可以解决你的烦恼,只有一个类哦,copy一下,就可以帮助你实现依赖注入;
simpleFactory是我在做小实验时,为了解决上面的问题,自己写的编码小工具,至少自己用起来很哈皮


SF代码:

package com.honeysuckle.webx.context;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;

/**
 * 类SF.java的实现描述:SimpleBeanFactory no one simpler than this one
 * 
 * @author yanghang 2010-9-16 下午04:43:05
 */
public class SF {

    private final Map<Class<?>, Object> context = new HashMap<Class<?>, Object>();

    /**
     * 向容器中放入某个实例
     * @param clazz 该实例的类型,可以是接口
     * @param object 该实例
     */
    public void put(Class<?> clazz, Object object) {
        this.context.put(clazz, object);
    }

    /**
     * 获取某个实例(单例) <br/>
     * 如果容器中不存在,会尝试初使化: <br/>
     * 1.调用构造函数,args为可能的构造函数的参数 <br/>
     * 2.会对该实例的set方法进行注入 <br/>
     * 3.最后会调用init()方法 <br/>     
     */
    public Object get(Class<?> clazz, Object... args) {
        Object object = this.context.get(clazz);
        if (object == null) {
            try {
                object = this.instanceClazz(clazz, args);
                this.instanceSetMethod(object);
                this.instanceInitMethod(object);
                this.put(clazz, object);
            } catch (Exception e) {
                return null;
            }
        }
        return object;
    }

    //获取某个实例的多例,每次都会重新产生该实例
    public Object getMulti(Class<?> clazz, Object... args) {
        Object object;
        try {
            object = this.instanceClazz(clazz, args);
            this.instanceSetMethod(object);
            this.instanceInitMethod(object);
        } catch (Exception e) {
            return null;
        }
        return object;
    }

    //初使化该类,调用构造方法
    private Object instanceClazz(Class<?> clazz, Object[] args) throws Exception {
        Object object = null;
        Class<?>[] clazzes = new Class[args.length];
        for (int i = 0; i < args.length; i++) {
            clazzes[i] = args[i].getClass();
        }
        Constructor<?>[] cons = clazz.getConstructors();
        for (Constructor<?> con : cons) {
            if (con.getParameterTypes().length != args.length) continue;
            object = con.newInstance(args);
        }
        return object;
    }

    // 根据set方法,进行注入
    private void instanceSetMethod(Object object) {
        Method[] methods = object.getClass().getDeclaredMethods();
        for (Method method : methods) {
            if (method.getName().indexOf("set") != 0) continue;
            Class<?>[] clazzes = method.getParameterTypes();
            if (clazzes.length != 1) continue;
            Class<?> pclazz = clazzes[0];
            try {
                Object pObject = this.get(pclazz);
                method.invoke(object, new Object[] { pObject });
            } catch (Exception e) {
                continue;
            }
        }
    }   

    // 初使化该类,调用init方法
    private void instanceInitMethod(Object object) {
        try {
            Method method = object.getClass().getMethod("init", new Class<?>[] {});
            method.invoke(object, new Object[] {});
        } catch (Exception e) {
            return;
        }
    }
}





用法示例
有类Bean1

public class Bean1 {

    private String hello;

    public void init() {
        this.hello = "hello kitty";
    }

    public void show() {
        System.out.println(this.hello);
    }
}



执行 TestSF

public class TestSF {

    private Bean1 bean;

    public void setBean(Bean1 bean) {
        this.bean = bean;
    }

    public void test() {
        this.bean.show();
    }

    public static void main(String[] args) {
        SF sf = new SF();
        TestSF test = (TestSF) sf.get(TestSF.class);
        test.test();
    }
}



输出:

hello kitty


15
6
分享到:
评论
15 楼 shansun123 2011-05-10  
哈哈  很不错哦  貌似仅byType啊  要是加上byName就更好了哦
14 楼 yfyh87 2011-04-14  
zhouxianglh 写道
//初使化该类,调用构造方法  
    private Object instanceClazz(Class<?> clazz, Object[] args) throws Exception { 


这里如果是int值转Object时会变成Integer然后会出问题吧.


你说的对,还包括,构造函数是接口,但是我想通过类来初使化的情况;
所以内部用
class.getConstructor(parameterTypes)

是找不到相应方法,但是却可以正常执行的

做为一个完整的健壮的窗口来说,这里需要通过 class.getConstructor(parameterTypes) 来找构造方法,但是parameterTypes要做类型,及继承和接口实现的处理;

当然,一个类的spring就偷了个懒

直接 
 Constructor<?>[] cons = clazz.getConstructors();        
        for (Constructor<?> con : cons) {
            if (con.getParameterTypes().length != args.length) continue;
            object = con.newInstance(args);
        }


这样,不管类型,只要参数长度一致,就执行,也可以避免一些转型的问题;

当然,这也有一些局限性; )
13 楼 zhouxianglh 2011-04-06  
//初使化该类,调用构造方法  
    private Object instanceClazz(Class<?> clazz, Object[] args) throws Exception { 


这里如果是int值转Object时会变成Integer然后会出问题吧.
12 楼 zui4yi1 2011-04-06  
留个脚印,好像是好东西
11 楼 zhangyou1010 2011-04-01  
多线程环境下,get方法需要同步。
10 楼 JustDone 2011-03-30  
JMX就可以了
9 楼 yfyh87 2011-03-29  
a496649849 写道
     if (con.getParameterTypes().length != args.length && con.getParameterTypes() != clazzes) continue;   

数组的比较不能直接使用等号吧,应该用Arrays.equals(a,b);

嗯,的确如此,已更正.多谢
8 楼 a496649849 2011-03-29  
     if (con.getParameterTypes().length != args.length && con.getParameterTypes() != clazzes) continue;   

数组的比较不能直接使用等号吧,应该用Arrays.equals(a,b);
7 楼 yfyh87 2011-03-28  
chan.d 写道
if (con.getParameterTypes().length != args.length) continue; 
            object = con.newInstance(args); 

这里的判断会有问题,

即使参数数量相同的2个构造函数,可能是参数类型不同的2个构造函数,即构造函数的重载。

楼主没有考虑到。


确实如此,已更正;
非常感谢
6 楼 yfyh87 2011-03-28  
873339698 写道
麻烦lz问一下

什么情况下
if (i == queue.size()) 会成立呢?


谢谢你的发现,
这一句应该一直都不会成立,是个多余的代码;
形成原因,是之前为了解决让循环依赖的bean也可以正常初使化起来,所以引入了queue的方式处理setMethod; 后来放弃了,这一句也是废代码,
已经更新了文章,把queue的处理删除了,现在应该简洁多了.
非常感谢
5 楼 873339698 2011-03-25  
麻烦lz问一下

什么情况下
if (i == queue.size()) 会成立呢?
4 楼 chan.d 2011-03-25  
if (con.getParameterTypes().length != args.length) continue; 
            object = con.newInstance(args); 

这里的判断会有问题,

即使参数数量相同的2个构造函数,可能是参数类型不同的2个构造函数,即构造函数的重载。

楼主没有考虑到。
3 楼 IPHONE3375 2011-03-25  
 
2 楼 56553655 2011-03-25  
好东西,取个更直接的名称吧:EasySpring,为Easy系列增加一新成员
1 楼 jackra 2011-03-25  
hello kitty 

hello world
亲切太多了

相关推荐

    spring的一个简单的例子

    这个“spring的一个简单的例子”压缩包可能是为了帮助初学者理解和入门Spring框架。以下是对这个简单例子中可能包含的知识点的详细解释: 1. **Spring 概述**: Spring 是一个开源的Java平台,它提供了一个全面的...

    一个简单的spring的应用

    在这个"一个简单的spring的应用"项目中,我们将探讨如何搭建一个基础的Spring环境并进行单元测试。 首先,我们需要理解Spring的核心概念——依赖注入(Dependency Injection,简称DI)。DI允许我们解耦组件间的依赖...

    最简单的一个spring注解实例

    在最简单的情况下,我们可以在一个类上使用 @Component 注解来告诉Spring容器,这个类是一个需要管理的bean。例如: ```java @Component public class MyComponent { // ... } ``` 2. **@Autowired** 注解:用于...

    一个简单的模仿spring的ioc实现

    这个“一个简单的模仿spring的ioc实现”项目旨在帮助开发者理解Spring Ioc的核心概念,并通过自己的代码实现来加深对这一机制的理解。 首先,Spring Ioc的主要目标是解耦应用程序组件。它通过管理对象的生命周期和...

    一个简单的Spring应用例子

    这个“一个简单的Spring应用例子”应该包含了一个基本的Spring配置和应用的构建结构,适合初学者理解和学习。 首先,我们来看一下这个压缩包中的文件: 1. `.classpath`:这是Eclipse IDE的一个项目配置文件,记录...

    一个简单的spring依赖注入的例子

    当Spring容器创建一个Bean时,会通过反射调用无参构造函数实例化对象,然后根据配置信息调用setter方法或使用构造函数参数进行依赖注入。 通过这个简单的例子,我们可以看到Spring如何通过反射机制实现依赖注入,...

    strut2+spring+springjdbctemplate做的简易登录系统

    Spring JDBC Template是Spring提供的一个简化数据库操作的工具,它封装了JDBC的繁琐部分,让开发者可以更专注于业务逻辑。 在这个“简易登录系统”中,Struts2主要承担用户界面和控制器之间的交互。用户在登录页面...

    快速搭建一个简易的spring web工程

    在src/main/java目录下,创建一个名为`com.yourpackage.controller`的包,并编写一个简单的Controller类,如`HelloController.java`: ```java package com.yourpackage.controller; import org.springframework....

    SpringJdbcTemplate封装工具类

    通过上述分析,我们可以看到SpringJdbcTemplate是一个强大且灵活的工具,它通过封装JDBC操作,使得数据库访问变得更加简单和安全。在实际开发中,合理利用其特性,可以有效提升开发效率和代码质量。

    第一个spring例子

    在这个"第一个spring例子"中,我们将探讨如何创建一个简单的Spring应用,它包含了client和server两部分,这通常意味着我们将构建一个客户端-服务器架构的应用。为了运行此示例,你需要安装MySQL数据库服务和Apache ...

    自主实现的简易Spring框架

    2. Bean定义:表示一个对象的配置信息,包括其类、属性、依赖等。 3. Bean工厂:根据Bean定义创建和管理Bean实例。 4. 注解解析器:解析类和方法上的注解,生成对应的Bean定义或切面规则。 5. AOP代理:用于拦截方法...

    spring第一个例子

    在"spring第一个例子"中,我们将创建一个简单的Spring应用程序。这个例子通常包括以下步骤: 1. **配置Spring**:首先,我们需要创建一个Spring的配置文件,例如`applicationContext.xml`。在这个文件中,我们会...

    简单spring aop 例子

    现在,我们来看如何创建一个简单的Spring AOP例子: 1. **定义切面(Aspect)**:切面是包含通知(Advice)和切入点(Pointcut)的类。通知定义了要执行的逻辑,切入点定义了何时执行。例如,我们可以创建一个名为`...

    一个spring例子

    在"一个spring例子"中,可能包含了一个简单的Spring MVC应用,这是Spring框架提供的Web层解决方案。Spring MVC提供了一种模型-视图-控制器(Model-View-Controller)架构,用于处理HTTP请求、路由到相应的处理器方法...

    Spring简单模拟Spring容器

    例如,我们可以使用`&lt;bean&gt;`标签在XML中定义一个bean,或者在Java类上使用`@Component`、`@Service`、`@Repository`和`@Controller`等注解来标记为Spring管理的组件。 在描述中提到的博客链接没有具体内容,但通常...

    Spring的第一个案例

    例如,我们可以创建一个简单的`HelloWorld`类,然后使用`@Component`注解将其标记为一个Spring Bean。 ```java @Component public class HelloWorld { public String sayHello() { return "Hello, Spring!"; } }...

    郁闷了,一个最简单的Spring小程序都没搞定

    标题中的“郁闷了,一个最简单的Spring小程序都没搞定”表明博主在尝试开发一个基于Spring框架的小程序时遇到了问题。这通常涉及到Spring的核心概念,如依赖注入(Dependency Injection, DI)、ApplicationContext、...

    struts+spring的一个简单项目

    在"struts+spring"的集成项目中,通常会有一个Spring配置文件(如:applicationContext.xml),用于定义bean,包括Action类、Service类和DAO类。这些bean可以通过Struts的ActionContext获取到,以便在Action中使用。...

    spring-boot-1-demo

    当 Controller 类与启动类位于同一个包或者其子包下时,Spring Boot 默认会扫描该包及其所有子包中的组件(如 @RestController 注解的类)。这种方式适用于小型项目,因为组件组织简单,易于管理。 2. **启动类和 ...

    Spring获取ApplicationContext对象工具类的实现方法

    在Spring中,典型的获取ApplicationContext对象的方式是使用ApplicationContext接口的一个实现类,如ClassPathXmlApplicationContext。这是一个根据给定XML文件的类路径的上下文实现。通常我们会在初始化Spring IoC...

Global site tag (gtag.js) - Google Analytics