spring学习笔记

来源:互联网 发布:儿童英语软件哪个好 编辑:程序博客网 时间:2024/05/10 11:17
spring 实现原理:
配置文件:
<beans>
<bean id="dao1" class="com.bjsxt.dao.impl.UserDAOImpl"></bean>
<bean id="userService" class="com.bjsxt.service.UserService" >
<property name="userDAO" bean="dao1"/>
</bean>
</beans>


装配方式:
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;


public class ClassPathXmlApplicationContext implements BeanFactory {
//新建map用于存放所有已经生成的类
private Map<String , Object> beans = new HashMap<String, Object>();

//模拟spring的ClassPathXmlApplication的生成方法
public ClassPathXmlApplicationContext() throws Exception {
//实例化SAXBuilder
SAXBuilder sb=new SAXBuilder();
   
//构造文档对象
   Document doc=sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml")); 
   //获取根元素HD
   Element root=doc.getRootElement(); 
   //取名字为bean的所有元素
   List list=root.getChildren("bean");
   //第一次循环获取第一层的bean
   for(int i=0;i<list.size();i++){
      Element element=(Element)list.get(i);
      String id=element.getAttributeValue("id");
      String clazz=element.getAttributeValue("class");
      Object o = Class.forName(clazz).newInstance();
      System.out.println(id);
      System.out.println(clazz);
      beans.put(id, o);
      
      //第二次循环装配所有类里面的属性为其他类的属性
      for(Element propertyElement : (List<Element>)element.getChildren("property")) {
      String name = propertyElement.getAttributeValue("name"); //userDAO
      String bean = propertyElement.getAttributeValue("bean"); //u
      Object beanObject = beans.get(bean);//UserDAOImpl instance
      
      String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
      System.out.println("method name = " + methodName);
      
      Class[] interfaces = beanObject.getClass().getInterfaces();
      Method m = o.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);
      m.invoke(o, beanObject);
      }
      
   }  
 
}


//获取指定的对象
public Object getBean(String id) {
return beans.get(id);
}
}




spring的实现原理:
1)获取根目录下面的最外层的bean放入到map中
2)装配上一层的bean里面的属性中为bean的属性
3)spring中类的位置最好还是按出现的先后排序




spring配置简介:






1.spring的属性配置:
为property属性赋值


第一种方法:
<property name="daoStatus" value="good" />
第二种方法:
<property name="daoId">
<value>888</value>
</property>




正常情况下,spring实例化bean的时候是使用的singleton就是单一实例
而prototype则是每一次实例化一次,每一次得到的都是原始的最新的


2.spring的实例化原理:


spring支持多种类型的实例化方式,如果是空的构造方法和带参数的构造方法都有的话,那么两种方式都是可以使用的.


(1)当一个类的构造方法依赖的是另外的一个bean的时候,需要使用下面的方式来指定
<constructor-arg>
  <ref bean="u"/>
</constructor-arg>


(2)当使用的是空的构造方法进行实例化的时候使用如下方式
<bean id="userService" class="com.bjsxt.service.UserService" scope="prototype" autowire="byType">
  <property name="daoId" ref="userDAO"/>
</bean>


3.为一个类的集合属性赋值:


<bean name="userDAO" class="com.bjsxt.dao.impl.UserDAOImpl">
<property name="sets">
<set>
<value>1</value>
<value>2</value>
</set>
</property>
<property name="lists">
<list>
<value>1</value>
<value>2</value>
<value>3</value>
</list>
</property>
<property name="maps">
<map>
<entry key="1" value="1"></entry>
<entry key="2" value="2"></entry>
<entry key="3" value="3"></entry>
<entry key="4" value="4"></entry>
</map>
</property>
</bean>




4.bean自动装配的设置:


1)在xml文件里面设置自动装配
<bean id="userService" class="com.bjsxt.service.UserService" scope="prototype" autowire="byType"/>
这种装配需要注意的是只能够为它提供一个可行的参数对象,否则也会出现
No unique bean of type [com.dada.dao.UserDao] is defined: expected single matching bean but found 2: [userDao1, userDao2]


5.bean里面的init-method方法和destroy-method方法指定bean的创建和消除所指定的方法
<bean id="userService" class="com.bjsxt.service.UserService" init-method="init" destroy-method="destroy" scope="prototype"/>
 
 
6.使用annonation之前需要在beans.xml文件中配置
<context:annotation-config />


1)bean的存活周期
<bean id="userService" class="com.bjsxt.service.UserService" init-method="init" destroy-method="destroy" scope="prototype"/>
这样配置的结果就是生成的bean并不会自动消失


2)在类中使用注解为属性赋值
配置文件:
<context:annotation-config />
<bean id="userDao1" class="com.dada.dao.impl.UserDaoImpl" />
<bean id="userDao2" class="com.dada.dao.impl.UserDaoImpl" />
<bean id="userService" class="com.dada.service.UserService"></bean>


类中设置
@Autowired
public UserService(@Qualifier("userDao1") UserDao userDao) {
super();
this.userDao = userDao;
}

3)使用@Resource


@Resource 的作用相当于 @Autowired,只不过 @Autowired 按 byType 自动注入,面 @Resource 默认按 byName 自动注入罢了。@Resource 有两个属性是比较重要的,分别是 name 和 type,Spring 将 @Resource 注释的 name 属性解析为 Bean 的名字,而 type 属性则解析为 Bean 的类型。所以如果使用 name 属性,则使用 byName 的自动注入策略,而使用 type 属性时则使用 byType 自动注入策略。如果既不指定 name 也不指定 type 属性,这时将通过反射机制使用 byName 自动注入策略。

@Resource(name = "office")
private Office office;




4)使用自动扫描和Component装配bean


如果要使用自动扫描首先要在beans的命名空间里面加上扫描的类
xmlns:context="http://www.springframework.org/schema/context"
之后需要加上
<context:annotation-config/>表示启用注解
<context:component-scan base-package="com"/>指定要扫描的包


例如:
@Component("userDao")//指定类的名称
public class UserDaoImpl implements UserDao {


@Override
public void add(User user) {
System.out.println("user\t"+user.getUsername()+"\thas been saved");
}
}


@Component("userService")
public class UserService {
//指定自动装配的对象的名称
@Resource(name="userDao")
private UserDao userDao;


public UserDao getUserDao() {
return userDao;
}

public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}

public void add(User user) {
userDao.add(user);
}
}


5)PostConstruct和PreDestroy用法
 从JavaEE5规范开始,Servlet中增加了两个影响Servlet生命周期的注解(Annotion);@PostConstruct和@PreDestroy。这两个注解被用来修饰一个非静态的void()方法。写法有如下两种方式:


@PostConstruct
public void init() {
System.out.println("对象创建成功!");
}
                                                                                    
或者


public @PostConstruct void init() {
System.out.println("对象创建成功!");
}


注解@PreDestroy用法和PostConstruct一样
@PreDestroy
public void destroy() {
System.out.println("对象被回收了!");
}


被@PostConstruct修饰的方法会在服务器加载Servle的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。PreDestroy()方法在destroy()方法执行执行之后执行