Spring之IOC
IOC
控制反转, 将由程序直接操控的对象调用权交给容器, 通过容器来实现对象的装配和管理.
容器即applicationContext.xml
第一个spring程序
1 // 创建容器对象, 一开始就初始化Bean 2 ApplicationContext context = new ClassPathXmlApplicationContext("day1202/applicationContext.xml"); 3 TestService service = (TestService) context.getBean("myService"); 4 service.test(); 5 6 // 跟ApplicationContext的区别在于对象的初始化顺序, getBean才初始化Service. 7 BeanFactory factory = new XmlBeanFactory(new ClassPathResource("day1202/applicationContext.xml")); 8 TestService service2 = (TestService) factory.getBean("myService"); 9 service2.test();
applicationContext中配置Bean.
1 <bean id="myService" class="day1202.ServiceImpl"/>
其实就相当于程序中直接写
TestService myService = new ServiceImpl();
工厂Bean
动态工厂
1 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); 2 TestService service = (TestService) context.getBean("myService"); 3 service.test();
1 <bean id="factory" class="day1202.ServiceFactory"/> 2 <bean id="myService" factory-bean="factory" factory-method="getService"/>
静态工厂
写法与动态工厂类似, 唯一区别在于
1 <bean id="myService2" class="day1202.StaticServiceFactory" factory-method="getService"/>
Bean的域
Singleton
当一个bean的作用域为singleton, 那么Spring IoC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。
换言之,当把一个bean定义设置为singlton作用域时,Spring IoC容器只会创建该bean定义的唯一实例。这个单一实例会被存储到单例缓存(singleton cache)中,
并且所有针对该bean的后续请求和引用都将返回被缓存的对象实例
Prototype
Prototype作用域的bean会导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时都会创建一个新的bean实例。
根据经验,对有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。
通常情况下,DAO不会被配置成prototype,因为DAO通常不会持有任何会话状态,因此应该使用singleton作用域。
Request
针对每次HTTP请求,Spring容器会根据loginAction bean定义创建一个全新的LoginAction bean实例, 且该loginAction bean实例仅在当前HTTP request内有效,
因此可以根据需要放心的更改所建实例的内部状态, 而其他请求中根据loginAction bean定义创建的实例,将不会看到这些特定于某个请求的状态变化。
当处理请求结束,request作用域的bean实例将被销毁。
Session
针对某个HTTP Session,Spring容器会根据userPreferences bean定义创建一个全新的userPreferences bean实例, 且该userPreferences bean仅在当前HTTP Session内有效。
与request作用域一样,你可以根据需要放心的更改所创建实例的内部状态,而别的HTTP Session中根据userPreferences创建的实例, 将不会看到这些特定于某个HTTP Session的状态变化。
当HTTP Session最终被废弃的时候,在该HTTP Session作用域内的bean也会被废弃掉。
Global Session
global session作用域类似于标准的HTTP Session作用域,不过它仅仅在基于portlet的web应用中才有意义。Portlet规范定义了全局Session的概念,
它被所有构成某个portlet web应用的各种不同的portlet所共享。在global session作用域中定义的bean被限定于全局portlet Session的生命周期范围内。
Bean后处理器
1 public class MyBeanProcessor implements BeanPostProcessor { 2 @Override 3 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 4 System.out.println("Bean初始化之前"); 5 return bean; 6 } 7 8 @Override 9 public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException { 10 System.out.println("Bean初始化之后" + beanName); 11 Object proxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(), 12 bean.getClass().getInterfaces(), 13 new InvocationHandler() { 14 @Override 15 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 16 Object object = method.invoke(bean, args); 17 System.out.println("动态代理修改Bean的方法返回值!"); 18 return object; 19 } 20 }); 21 // 返回代理对象 22 return proxy; 23 } 24 }
基于注解的Bean生命周期管理
1 @PostConstruct //初始化 2 @PreDestory //销毁
基于XML & 注解实现注入
XML设值注入
1 <bean id="mySchool1" class="day1204.School"> 2 <property name="name" value="heihei School"/> 3 </bean> 4 5 <bean id="myStudent2" class="day1204.Student"> 6 <property name="name" value="Alice"/> 7 <property name="age" value="12"/> 8 <property name="mySchool" ref="mySchool"/> 9 </bean>
注解设置注入
1 @Scope("prototype") 2 @Component("myPerson") 3 public class Person { 4 5 @Value("123") 6 private int page; 7 @Value("Alice") 8 private String pname;
构造注入
1 <bean id="myStudent1" class="day1204.Student"> 2 <constructor-arg value="23"/> 3 <constructor-arg name="name" value="Anna"/> 4 <constructor-arg index="2" ref="mySchool1"/> 5 </bean>
集合属性注入
1 <bean id="mySom" class="day1205.Som"> 2 <property name="schools"> 3 <array> 4 <ref bean="mySchool1"/> 5 <ref bean="mySchool2"/> 6 </array> 7 </property> 8 9 <property name="strs"> 10 <array> 11 <value>str1</value> 12 <value>str2</value> 13 </array> 14 </property> 15 16 <property name="lists" value="list1, list2"> 17 </property> 18 19 <property name="sets" value="set1, set2"> 20 </property> 21 22 <property name="maps"> 23 <map> 24 <entry key="map-key1" value="map-value1"/> 25 <entry key="map-key2" value="map-value2"/> 26 </map> 27 </property> 28 29 <property name="pros"> 30 <props> 31 <prop key="pros-key1">props-value1</prop> 32 <prop key="pros-key2">props-value2</prop> 33 </props> 34 </property> 35 </bean>
XML域属性注入
1 <bean id="myStudent" class="day1204.Student" autowire="byName"/>
1 <bean id="myStudent" class="day1204.Student" autowire="byType"/>
注解域注入
1 @Autowired // byType 2 @Qualifier("mySchool") //byName
SPEL注入
1 <bean id="myStudent" class="day1204.Student" autowire="byName"> 2 <property name="name" value="#{myPerson.pname}"/> 3 <property name="age" value="#{myPerson.page > 25 ? 25: myPerson.page}"/> 4 </bean> 5 6 <bean id="myPerson" class="day1205.Person"> 7 <property name="pname" value="per1"/> 8 <property name="page" value="#{T(java.lang.Math).random() * 50}"/> 9 </bean>
为应用指定多个配置文件
- 平等关系
1 // 数组 2 ApplicationContext context1 = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml", "day1205/applicationContext2.xml"}); 3 // 通配符 4 ApplicationContext context2 = new ClassPathXmlApplicationContext("applicationContext-*.xml");
- 包含关系
1 <import resource="classpath:day1205/applicationContext3.xml"/> 2 <import resource="classpath:day1205/applicationContext*.xml"/>
JavaConfig充当Spring容器
1 @Configuration 2 //充当spring容器, 所有的bean都由他创建 3 public class MyJavaConfig { 4 5 @Bean(name="myPerson") 6 public Person createPerson() { 7 return new Person(18, "Alice"); 8 } 9 }
1 <beans xmlns="http://www.springframework.org/schema/beans" 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns:context="http://www.springframework.org/schema/context" 4 xsi:schemaLocation=" 5 http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/context 8 http://www.springframework.org/schema/context/spring-context.xsd"> 9 10 <context:component-scan base-package="day1206"/>
其他
如果XML和注解同时对Bean进行注入, 那么XML优先级高于注解
Spring下载地址