sioc帮助手册

1.什么是ioc?

IOC就是控制反转(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题。 控制反转还有一个名字叫做依赖注入(Dependency Injection)。简称DI。

2.功能说明

  1. 支持配置文件.
  2. 支持AOP拦截
  3. 动态代理和代理创建
  4. 动态注册配置,如果不想使用XML来配置可以使用动态注册。
  5. @Bean便签可以自动注册

3.配置说明

<?xml version="1.0" encoding="UTF-8"?>
<sioc namespace="global">
   <bean name="类名,用来调用" class="创建的类路径" create="创建方法" singleton="是否为单列(true,false)">
        <string name="参数名">参数值</string>
   </bean>
   <include>包含其他的配置文件</include>
</sioc>
name和id是一样的,只是为了兼容spring的结构。为什么要兼容?如果你是一个开发的时候,喜欢跳来跳去的就会发现它的好处。 上边 中 global表示命名空间,默认命名空间就是 global,这样你就可以在多个软件项目中为你的bean分类了. 这部分和Spring的配置 很相似,但参数配置上为了支持类型转换,感觉清晰改用了变量名称来转换.

sioc配置类型说明:

支持类型表 类型
<string name="参数名">参数值</string> 字符串
<int name="参数名">参数值</int> int 或者integer 整数
<boolean name="参数名">参数值</boolean>或者bool 布尔
<long name="参数名">参数值</long> 长整型
<float name="参数名">参数值</float> 单精度
<double name="参数名">参数值</double> 双精度
<date name="参数名">参数值</date> 日期
<ref name="参数名">参数值</ref> ioc中配置的其他bean
数组参数 class部分填写string,int,long,boolean,....
<array name="参数名" class="单个参数类型(string,int,boolean...)">
    <value>参数值1</value>
     <value>参数值1</value>
</array>     
map配置
<map name="参数名">
 <value key="键值1" class="本参数类型">参数值1</value>
 <value key="键值2" ref="是否为bean资源(true,false)">参数值1</value>
</map>     
list 类
<list name="参数名" class="单个参数类型(string,int,boolean...)">
    <value>参数值1</value>
    <value>参数值1</value>
</list>     

sioc配置支持的变量:

支持类型表 类型
@rootNamespace 当前环境命名空间根名称(/最前边部分,一般为软件目录名称)
@namespace 当前命名空间名称
这两个变量对应你所配置的环境空间 例如我们可以配置DAO将数据分类保存到各自到空间下
        <bean id="uploadFileDAO" class="com.jspx.txweb.dao.impl.UploadFileDAOImpl" singleton="true">
            <ref name="soberFactory">jspxSoberFactory</ref>
            <string name="className">jspx.jcms.table.UploadFile</string>
            <string name="namespace">@rootNamespace</string>
        </bean>

4.初始化部分

系统的初始化部分代码。
    //导入Ioc配置 begin  
    BeanFactory beanFactory = EnvFactory.getBeanFactory();  
    IocContext iocContext = new ConfigureContext(jspxConfiguration.getConfigFile());  
    iocContext.setValueMap(envTemplate.getVariableMap());  
    beanFactory.setIocContext(iocContext);  
    //导入Ioc配置 end  
以后就可以通过 beanFactory 得到你配置的类对象了。 实际使用中我们不需要这么复杂来初始化。实际使用的时候是整合在一块的。只需要初始化构架后就可以使用。 如果在tomcat,resin这些容器中只要配置了过滤,或者servlet就会自动初始化了。 如果是软件可以使用下边代码初始化。JspxNetApplicaion.autoRun();而你需要做的就是完成配置。

5.高级例子

因为基本用法很象Spring ,也比较简单我主要做一个aop 带拦截的例子给大家. 配置文件 ioc.xml
<?xml version="1.0" encoding="UTF-8"?>
<sioc namespace="global">
    <bean name="realSubject" class="com.jspx.sioc.test.RealSubject" singleton="true">
    </bean>

    <bean name="testAopBean" class="com.jspx.sioc.test.TestAopBean" singleton="true">
    </bean>

    <bean name="testInterceptor" class="com.jspx.sioc.test.TestInterceptor" singleton="true">
    </bean>

    <bean name="subject" class="com.jspx.sioc.aop.AopDynamicProxy" create="proxy" singleton="false">
       <ref name="target">realSubject</ref>
       <ref name="aopBean">testAopBean</ref>
       <ref name="methodInterceptor">testInterceptor</ref>
    </bean>
</sioc>
被拦截和AOP的类
package com.jspx.sioc.test;
public class RealSubject implements Subject
{
       public RealSubject()
       {

       }

       public String request()
       {
           System.out.println("真实运行,如果被拦截就不会运行这里了");
           return "真实运行";
       }
}
AOP类(用的地方很多,可以用在权限,日志等)
package com.jspx.sioc.test;

import com.jspx.sioc.AopBean;
import java.lang.reflect.Method;

public class TestAopBean implements AopBean
{
     public void before(Object proxy, Method method, Object[] args)
     {
          System.out.println("开始before calling " + method);
     }

     public void after(Object proxy, Method method, Object[] args)
     {
          System.out.println("结束after calling " + method);
     }

}
拦截器(一般主要用在缓存上)
package com.jspx.sioc.test;

import com.jspx.sioc.MethodInterceptor;
import java.lang.reflect.Method;
public class TestInterceptor implements MethodInterceptor
{
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
     {
          //args 你调用的方法参数
          System.out.println("你调用的方法名:" + method.getName());
          return "拦截和就返回这个变量";
         //如果不拦截,就运行下边的方法,可以得到拦截方法的返回值
         // return method.invoke(proxy,args);
     }
}
调用代码
String fileName = "ioc.xml";
EntryFactory beanFactory = new EntryFactory();
beanFactory.setIocContext(new ConfigureContext(fileName));
Subject subject = (Subject) beanFactory.getBean("subject");
System.out.println("end:" + subject.request());

6.动态注册

        LifecycleObject lifecycleObject = new LifecycleObject();
        lifecycleObject.setName("调用名称");
        lifecycleObject.setClassName("创建的类名");
        lifecycleObject.setSingleton(true);
        //设置其他属性
        beanFactory.registerSingletonBean(lifecycleObject.getName(),"命名空间",lifecycleObject);
如果你希望多例模式的时候延时载入其他配置的bean你可以设置变量为: siocLoad:调用名$命名空间这样的格式.

7.annotation标签

ref 的参数说明
String name(); //sioc中的名称
String namespace() default "global"; //命名空间
//载入的时候如果为true,并且没有这个对象的时候不报错,否则会报错误
boolean test() default false;
< code >test为true的时候,namespace自动测试载入,载入的命名空间为配置的空间名,如果是多层配置后,载入的还是配置的空间名,
不会自动切换到新的空间名下,主要是使用在夸命名空间的拦截器上需要考虑到。
在程序中如何自动载入
    private PermissionManage permissionManage; 
    //注入的时候是使set+字段名称  
    @Ref(name = "sioc名称", namespace = "sioc中的命名空间")  
    public void setPermissionManage(PermissionManage permissionManage)  
    {  
        this.permissionManage = permissionManage;  
    }  
简写
@Ref
private PermissionManage permissionManage; 

8.AOP Bean

AOP Bean是当系统启动的时候会运行一次init,当系统结束的时候(正常推出)会运行一次destroy,一些后台定时服务可以写成bean放在这里。 有点相window的后台服务。可以在sioc中配置,beanArray部分就是你加入其他需要这样执行的地方。
<!--Aop Boost begin-->
<bean id="aopBootBean" class="com.jspx.sioc.aop.AopAppCommandImpl" singleton="true">
<bool name="enable">${aopboot}</bool>
<array name="beanArray" class="string">
<value>aopSchedulerTask</value>
</array>
</bean>
<bean id="aopSchedulerTask" class="com.jspx.task.AopSchedulerTask" singleton="true">
<int name="sleepTime">58</int>
<ref name="soberFactory">jspxSoberFactory</ref>
</bean>
接口如下,你需要继承这个接口来创建AOP Bean
public abstract class AbstractAopBean implements AopAppBean
{
    public static final java.lang.String SUCCESS = "success";
    public static final java.lang.String NONE = "none";
    public static final java.lang.String ERROR = "error";
    public static final java.lang.String INPUT = "input";
    public static final java.lang.String LOGIN = "login";

    public abstract java.lang.String init() throws java.lang.Exception;

    public abstract java.lang.String destroy() throws java.lang.Exception;

}

9.PropertySource 配置载入,这里和spring差不多

testp.properties
# 配置persion
# idea 默认UTF-8
persion.name=张三
persion.age=18
persion.birth=2018/02/11
persion.isBoss=true
persion.lists=1,2,3
persion.dog.name=dog
persion.dog.age=15
persion.last-name=王五
persionxxx=asdfasdfsda
import com.jspx.sioc.annotation.PropPrefix;
import com.jspx.sioc.annotation.PropertySource;
import com.jspx.sioc.annotation.Value;
import java.util.Date;
import java.util.List;
@PropertySource(value = "classpath:testp.properties")
@PropPrefix(prefix = "persion" )
public class Persion {
    private String name;
    private Integer age;
    private boolean isBoss;
    private Date birth;
    private String lastName;
    private List<Object> lists;
    @Value("${persionxxx}")
    private String publicKey;
    //set get ...
}
上边 下边是动态创建方式,也可以配置 Persion 到ioc 中载入, 其他说明:有指定文件将读取指定的变量部分,如果不指定就是系统默认的配置环境
         BeanFactory beanFactory = EnvFactory.getBeanFactory();
        LifecycleObject lifecycleObject = new LifecycleObject();
        lifecycleObject.setClassName(Persion.class.getName());
        Persion persion = (Persion)beanFactory.createEntry(lifecycleObject);
        System.out.println("----------------result=" + new JSONObject(persion));

10. @Bean直接注释

说了这么多其实只用一个注释标签就可以注释了 @Bean(namespace = "命名空间", singleton = true)

11.什么时候使用单列

很多人不明白什么时候使用单列,什么时候使用多态,其实很简单,单列不会释放内存,一直存在内存中。如果你的程序中都使用一个bean对象。并且不会在bean中 根据其他变量来计算,并且bean里边没有大数据保存,那么你就应该使用单列。单列的运行速度也很快。 一般简单的DAO这些都应该使用单列比较好,但如果你的DAO中还要区分命名空间来处理数据,那么就应该使用多例。 还有就是如果你的cpu数量很多,希望得到更搞的并发性能可以使用多例模式。cpu少了,使用多例模式反而不好,占用内存更多。