Spring学习

所有内容源自《Spring3.x企业应用开发实战》的学习。留作备查。


目录:

一、标记

二、资源

三、加载配置文件

四、Spring的bean生命周期

五、bean属性注入配置

六、作用域 scope="singleton|prototype|request|session|blobalSession"


一、标记

1. @Repository: 最初来自于DDD,表示对storage,retireval,search层的封装。这里多用作traditional J2EE模式中的DAO层表示。

2. @Component: 主要用来被spring自动扫描

3. @Autowired: 自动装配。Spring容器启动时会扫描到该标记,从容器中找到相应的bean注入给该标记对应的Field。(一般都是Field)

4. @Service: 标记三层架构中的中间业务层。

5. @Controller:  用于Spring MVC控制器,类似于struts的Action

6.@RequestMapping: 用于Spring MVC的地址映射,请求根据该标记找到对应的处理逻辑


和XML配置对比:

  1)@Component[("xxx")],@Repository,@Service,@Controller相当于<bean id="xxx">标签

  2)@Autowired,@Qualifier("xxx")类似于<property>标签。默认按类型注入。而@Resource默认按名称注入。

  3)@PostConstruct,@PreDestroy类似于<bean init-method="" destroy-method="">

  4) @Scope和@Lazy(true) 类似于<bean scope="" lazy-init="">


二、资源:

// Resource的使用
String path = "C:\\Users\\zhanghui\\Workspaces\\MyEclipse 8.5\\springdemo\\src\\script.sql";
			Resource res1 = new FileSystemResource(path);
			Resource res2 = new ClassPathResource("script.sql");
			System.out.println(res1.getFilename());
			System.out.println("length: " + res1.contentLength());
			System.out.println("getDescription: " + res1.getDescription());
			System.out.println(res2.getFilename());
			
			System.out.println("============ EncodedResource =============");
			EncodedResource encRes = new EncodedResource(res1, "UTF-8");
			String content = FileCopyUtils.copyToString(encRes.getReader());
			System.out.println("Encoded: " + content);

// web环境下的resource
String path = "C:\\Users\\zhanghui\\Workspaces\\MyEclipse 8.5\\springdemo\\src\\script.sql";
			Resource res1 = new FileSystemResource(path);
			Resource res2 = new ClassPathResource("script.sql");
			System.out.println(res1.getFilename());
			System.out.println("length: " + res1.contentLength());
			System.out.println("getDescription: " + res1.getDescription());
			System.out.println(res2.getFilename());
			
			System.out.println("============ EncodedResource 对Resource指定编码格式 =============");
			EncodedResource encRes = new EncodedResource(res1, "UTF-8");
			String content = FileCopyUtils.copyToString(encRes.getReader());
			System.out.println("Encoded: " + content);

// 根据路径模式匹配去获取Resource
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
			Resource resources[] = resolver.getResources("classpath:com/baobaotao/**/*.class"); // 或者"classpath*:com/baobaotao/**/*.xml"
			for (Resource r : resources) {
				System.out.println(r.getFilename());
			}

三、加载配置文件

// 非web环境
// BeanFactory
		ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
		Resource res = resolver.getResource("classpath:com/baobaotao/service/ZHTest.xml");
		BeanFactory bf = new XmlBeanFactory(res);
		Car c = bf.getBean("mycar", Car.class);
		c.fun();
		
		// ApplicationContext
		ApplicationContext ac = new ClassPathXmlApplicationContext("com/baobaotao/service/ZHTest.xml");
		Car c2 = (Car)ac.getBean("mycar");
		c2.fun();

// web环境
// 1.配置web.xml
<context-param>
  	<param-name>contextConfigLoation</param-name>
  	<param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  
  <listener>
  	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

// 2.获取WebApplicationContext
WebApplicationContext wac = (WebApplicationContext)request.getSession().getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
			WebApplicationContext wac2 = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());
			System.out.println(wac == wac2);
			Car c = wac.getBean("mycar");


四、Spring的bean生命周期

/*
1.Bean自身方法: 构造函数,setter,init-method,destroy-method
2. bean级生命周期接口: BeanNameAware,BeanFactoryAware,InitializingBean,DisposableBean.
3. 容器级别的后处理器:BeanPostProcessor
*/

// 1.定义bean
public class Car implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean{
	
	
	private String name;
	
	public void setName(String name) {
		System.out.println("Car.setName("+name+") called!!");
		this.name = name;
	}
	
	public Car() {
		System.out.println("Car.Car() called!!");
	}
	
	public void fun() {
		System.out.println("Car.fun() called!! I am " + this.name);
	}
	
	public void init_method() {
		System.out.println("Car.init_method() called");
	}
	
	public void destroy_method() {
		System.out.println("Car.destroy_method() called");
	}

	public void setBeanName(String name) {
		System.out.println("BeanNameAware.BeanNameAware(" + name + ") called");
	}

	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		System.out.println("BeanFactoryAware.setBeanFactory() called");
	}

	public void afterPropertiesSet() throws Exception {
		System.out.println("InitializingBean.afterPropertiesSet() called");
	}

	public void destroy() throws Exception {
		System.out.println("DisposableBean.destroy() called");
	}
}

// 2.定义后处理器
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter{

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName)
			throws BeansException {
		if ("mycar".equals(beanName)) {
			System.out.println("MyInstantiationAwareBeanPostProcessor.postProcessAfterInitialization() called");
		}
		return bean;
	}

	@Override
	public boolean postProcessAfterInstantiation(Object bean, String beanName)
			throws BeansException {
		if ("mycar".equals(beanName)) {
			System.out.println("MyInstantiationAwareBeanPostProcessor.postProcessAfterInstantiation() called");
		}
		return true;
	}

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName)
			throws BeansException {
		if ("mycar".equals(beanName)) {
			System.out.println("MyInstantiationAwareBeanPostProcessor.postProcessBeforeInitialization() called");
		}
		return bean;
	}

	@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass,
			String beanName) throws BeansException {
		if ("mycar".equals(beanName)) {
			System.out.println("MyInstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation() called");
		}
		return null;
	}

	@Override
	public PropertyValues postProcessPropertyValues(PropertyValues pvs,
			PropertyDescriptor[] pds, Object bean, String beanName)
			throws BeansException {
		if ("mycar".equals(beanName)) {
			System.out.println("MyInstantiationAwareBeanPostProcessor.postProcessPropertyValues() called");
		}
		return pvs;
	}

}
// 3. 配置
<bean id="mycar" class="com.baobaotao.service.Car" init-method="init_method" destroy-method="destroy_method" scope="prototype">
	<property name="name" value="jack"></property>
	</bean>

// 4.实例化容器并获取bean,观察生命周期方法的执行
// BeanFactory
		ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
		Resource res = resolver.getResource("classpath:com/baobaotao/service/ZHTest.xml");
		BeanFactory bf = new XmlBeanFactory(res);
		((ConfigurableBeanFactory)bf).addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
		Car c = bf.getBean("mycar", Car.class);
		c.setName("allei");
		c.fun();
		
		System.out.println("===================");
		Car c2 = bf.getBean("mycar", Car.class);
		System.out.println("c1==c2" + (c==c2));
		
		((XmlBeanFactory)bf).destroySingletons();

// 5.输出:
MyInstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation() called
Car.Car() called!!
MyInstantiationAwareBeanPostProcessor.postProcessAfterInstantiation() called
MyInstantiationAwareBeanPostProcessor.postProcessPropertyValues() called
Car.setName(jack) called!!
BeanNameAware.BeanNameAware(mycar) called
BeanFactoryAware.setBeanFactory() called
MyInstantiationAwareBeanPostProcessor.postProcessBeforeInitialization() called
InitializingBean.afterPropertiesSet() called
Car.init_method() called
MyInstantiationAwareBeanPostProcessor.postProcessAfterInitialization() called
Car.setName(allei) called!!
Car.fun() called!! I am allei
===================
Car.Car() called!!
MyInstantiationAwareBeanPostProcessor.postProcessAfterInstantiation() called
MyInstantiationAwareBeanPostProcessor.postProcessPropertyValues() called
Car.setName(jack) called!!
BeanNameAware.BeanNameAware(mycar) called
BeanFactoryAware.setBeanFactory() called
MyInstantiationAwareBeanPostProcessor.postProcessBeforeInitialization() called
InitializingBean.afterPropertiesSet() called
Car.init_method() called
MyInstantiationAwareBeanPostProcessor.postProcessAfterInitialization() called
c1==c2false

// ********************************
// 6.如果使用ApplicationContext进行初始化,和用BeanFactory初始化的区别:
//    -- 可以定义BeanFactoryPostProcessor后处理器,让我们有机会在获取bean之前进行再次修改
//    -- 所有的后处理器不需要通过编程的方式加到容器中,只需要直接在配置文件里面进行普通bean的配置即可。spring会自动感知这些后处理器
// ********************************

// 6.1 定义BeanFactoryPostProcessor
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor{

    public void postProcessBeanFactory(
            ConfigurableListableBeanFactory beanFactory) throws BeansException {
        BeanDefinition bd = beanFactory.getBeanDefinition("mycar");
        bd.getPropertyValues().addPropertyValue("name", "xxxxxxxx");
        System.out.println("MyBeanFactoryPostProcessor.postProcessBeanFactory() called");
    }

}

// 6.2 配置后处理器
<bean id="myBeanFactoryPostProcessor" class="com.baobaotao.service.MyBeanFactoryPostProcessor"></bean>
<bean id="myInstantiationAwareBeanPostProcessor" class="com.baobaotao.service.MyInstantiationAwareBeanPostProcessor"></bean>

// 6.3 ApplicationContext初始化
ApplicationContext ac = new ClassPathXmlApplicationContext("com/baobaotao/service/ZHTest.xml");
        Car c2 = (Car)ac.getBean("mycar");
        c2.setName("allei");
        c2.fun();
        System.out.println("===================");
        Car c3 = (Car)ac.getBean("mycar");
        c3.setName("Nani");
        c3.fun();

// 6.4 输出
MyBeanFactoryPostProcessor.postProcessBeanFactory() called
MyInstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation() called
Car.Car() called!!
MyInstantiationAwareBeanPostProcessor.postProcessAfterInstantiation() called
MyInstantiationAwareBeanPostProcessor.postProcessPropertyValues() called
Car.setName(xxxxxxxx) called!!
BeanNameAware.BeanNameAware(mycar) called
BeanFactoryAware.setBeanFactory() called
MyInstantiationAwareBeanPostProcessor.postProcessBeforeInitialization() called
InitializingBean.afterPropertiesSet() called
Car.init_method() called
MyInstantiationAwareBeanPostProcessor.postProcessAfterInitialization() called
Car.setName(allei) called!!
Car.fun() called!! I am allei
===================
Car.Car() called!!
MyInstantiationAwareBeanPostProcessor.postProcessAfterInstantiation() called
MyInstantiationAwareBeanPostProcessor.postProcessPropertyValues() called
Car.setName(xxxxxxxx) called!!
BeanNameAware.BeanNameAware(mycar) called
BeanFactoryAware.setBeanFactory() called
MyInstantiationAwareBeanPostProcessor.postProcessBeforeInitialization() called
InitializingBean.afterPropertiesSet() called
Car.init_method() called
MyInstantiationAwareBeanPostProcessor.postProcessAfterInitialization() called
Car.setName(Nani) called!!
Car.fun() called!! I am Nani





五、Bean属性注入配置

1. Spring IOC容器主要是用来对bean进行管理,主要使用反射,在使用后处理器时使用了动态代理。
   基本原理就是通过反射的方式取创建bean的实例(prototype每次都会创建,singleton方式只创建一次)。
   bean的属性注入分为setter和构造方法注入(还有工厂注入,很少用)。也是使用反射的方式取注入。
2. Spring注入方式
  1) 字面常量。针对基本类型、包装类和String。 主要特殊字符要转义: <(<) >(>) &(&) "(")  '(') 
  2) 引用其他bean。 <ref bean="otherBeanId" />
  3)  内部bean。 
	<bean id="outerBean" class="...">
		<property name="car">
			<bean class="..." />  <!-- 独立的bean定义 -->
		</property>
	</bean>
  4) null值   <property name="car"> <null/> </property>
  5) list属性 (也适用于基本类型、包装类型、string类型的数组。如String[], int[], Integer[])
	<property name="mylist">
		<list>
			<value>list_item1</value>
			<value>list_item2</value>
			<value>list_item3</value>
		</list>
	</property>
  6) set属性
	<property name="myset">
		<set>
			<value>list_item1</value>
			<value>list_item2</value>
			<value>list_item3</value>
		</set>
	</property>
  7) map属性
	<property name="mymap">
		<map>
			<entry>
				<key><value>key1</value> </key>
				<value>value1</value>
			</entry>
			<entry>
				<key><value>key2</value> </key>
				<value>value2</value>
			</entry>
<entry key="map_key3" value="map_value3" />
 <!-- 对于key-value都是对象的情况
			<entry>
				<key><ref bean="xx" /> </key>
				<ref bean="xx"/>
			</entry>
			-->
		</map>
	</property>
	
  8) properties属性
	<property name="myprops">
		<props>
			<prop key="key1">value1</prop>
			<prop key="key2">value2</prop>
			<prop key="key3">value3</prop>
		</props>
	</property>


七、FactoryBean

// FactoryBean用来控制bean的实例化过程,不再交给spring容器去实例化
public class CarFactoryBean implements FactoryBean<Car> {

	public Car getObject() throws Exception {
		Car c = new Car();
		c.setColor("black");
		c.setName("Ford");
		return c;
	}

	public Class<?> getObjectType() {
		return Car.class;
	}

	public boolean isSingleton() {
		return false;
	}

}

// 配置
<bean id="mycar4" class="com.baobaotao.service.CarFactoryBean"/>

// 使用
ApplicationContext ac = new ClassPathXmlApplicationContext("com/baobaotao/service/ZHTest.xml");

		Car c4 = (Car)ac.getBean("mycar4"); // 实际上市调用FactoryBean的getObject()方法
		c4.fun();








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值