Spring_Bean

一 、spring IOC & DI

IOC   inversion of Controller 控制反转。
由我们自己实例化的对象交给spring容器来实始化。这时对象的初始化的权利就会反转。

DI dependency injection 依赖注入
在spring框架负责创建Bean对象时,动态将依赖对象注入到Bean组件

1.提供User实体类

public interface Person {
		void desc();
	}
	
	public class User implements Person{
		private String name;
		public String getName() { return name; }
		public void setName(String name) { this.name = name; }
		@Override
		public void desc() { System.out.println("hi~"+name);}
	}
	

2.编写applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
	<beans xmlns="http://www.springframework.org/schema/beans"
		   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		   xsi:schemaLocation="http://www.springframework.org/schema/beans
			http://www.springframework.org/schema/beans/spring-beans.xsd">
		<bean id="u" class="com.b3a4a.ioc.User"> 
			<!-- 通过依赖注入将cnB3a4a这个值注到实例对象的name属性中 -->
			<property name="name" value="cnB3a4a"></property> 
		</bean>
	</beans>
注意:

<bean></bean>标签注意事项

	在开发中可以使用id或name 
	id它遵守xml规范,名称中不能包含特殊符号 		
	name它是为了更好的扩展,在name中可以包含一些特殊符号,例如"_"

3.获取对象实例

	@Test
	public void test(){
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person u = (Person) applicationContext.getBean("u");
		u.desc();
	}

二、Bean创建&Bean作用范围

Bean工厂结构

BeanFactory(根接口)
	ApplicationContext(子接口)
		ClassPathXmlApplicationContext
		FileSystemXmlApplicationContext
		AnnotationConfigApplicationContext
		
		org.springframework.web.context.WebApplicationContext(ApplicationContext的子接口)
		
BeanFactory和ApplicationContext区别
	BeanFactory延时加载(什么时候需要什么时候创建)
	ApplicationContext立即加载(加载配置文件时就会创建)

Bean创建的3种方式

A)通过无参数构造来创建
B)通过静态工厂方法来创建	
C)通过实例工厂方法来创建
使用spring创建Bean步骤
	
	1.创建接口(IBean)和实现类(IBeanImpl)
		public interface IBean {
			void desc();
		}

		public class BeanImpl implements IBean {
			@Override
			public void desc() {
				System.out.println("hello !!!");
			}
		}
		
		public class StaticBeanFactory {
			//------方式二------
			//通过通过静态工厂方法来创建
			public static BeanImpl createBean(){
				return new BeanImpl();
			}
		}
		
		
		//------方式三------
		//通过实例工厂方法来创建
		public class BeansFactory{
			public BeanImpl getBean(){
				return new BeanImpl();
			}
		}
	
	
	2.编写applicationContext.xml
	
		<?xml version="1.0" encoding="UTF-8"?>
		<beans xmlns="http://www.springframework.org/schema/beans"
			   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
			   xsi:schemaLocation="http://www.springframework.org/schema/beans
				http://www.springframework.org/schema/beans/spring-beans.xsd">
		   <!--方式一-->
			<!--通过无参构造创建bean-->
			<bean id="bean" class="com.b3a4a.ioc.BeanImpl"> </bean>

			<!--方式二-->
			<!--通过静态工厂方法创建bean-->
			<bean id="bean" class="com.b3a4a.ioc.StaticBeanFactory" factory-method="createBean"> </bean>

			<!--方式三-->
			<!--通过工厂方法创建bean-->
			<bean id="beanFactory" class="com.b3a4a.ioc.BeansFactory"> </bean>
			<bean id="bean" factory-bean="beanFactory" factory-method="getBean"> </bean>

		</beans>
		
	3.通过工厂来创建对象
	
		a)通过BeanFactory来获取
			BeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
		b)通过ClassPathXmlApplicationContext来获取
			ApplicationContext factory = new ClassPathXmlApplicationContext("applicationContext.xml");
					
		IBean bean = (IBean) factory.getBean("bean");
	
	
配置Bean的作用域

	在applicationContext.xml文件中bean标签上配置scope属性

	singleton		单例 代表在spring ioc容器中只有一个Bean实例 (默认的scope)
	prototype	多例 每一次从spring容器中获取时,都会返回一个新的实例
	request 		用在web开发中,将bean对象request.setAttribute()存储到request域中
	session 		用在web开发中,将bean对象session.setAttribute()存储到session域中
	
	<?xml version="1.0" encoding="UTF-8"?>
		<beans xmlns="http://www.springframework.org/schema/beans"
			   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
			   xsi:schemaLocation="http://www.springframework.org/schema/beans
				http://www.springframework.org/schema/beans/spring-beans.xsd">
		<bean id="bean" class="com.b3a4a.ioc.BeanImpl" scope="singleton"> </bean>	
	</beans>
	
	注意:
		作用于为prototype时创建对象为延迟创建  创建对象时
		作用于为singleton时创建对象为立即创建	 加载容器时		

三、SpringBean注入
1、属性注入

1.创建实体类Car和Person

	public class Car {
		private String name;
		private double price;
		public Car() {}
		public Car(String name, double price) {
			this.name = name;
			this.price = price;
		}
		//省略get/set方法
	}
	
	public class Person {
		private String name;
		private Car car;
		//省略get/set方法
	}


2.配置applicationContext.xml文件

	<?xml version="1.0" encoding="UTF-8"?>
	<beans xmlns="http://www.springframework.org/schema/beans"
		   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		   xsi:schemaLocation="http://www.springframework.org/schema/beans
			http://www.springframework.org/schema/beans/spring-beans.xsd">
		<!-- 使用setter方法对car的属性进行注入 -->
		<bean id="mCar" class="com.b3a4a.di.Car">
			<property name="name" value="宝马" />
			<property name="price" value="500000" />
		</bean>
		<bean name="person" class="com.b3a4a.di.Person">
			<property name="name" value="b3a4a" />
			<!-- ref引用其它bean的id或name值 -->
			<property name="car" ref="mCar" />
		</bean>
		
		<!-- 使用构造方法对car的属性进行注入 -->
		<bean id="benzCar" class="com.b3a4a.di.Car">
			<constructor-arg name="name value="奔弛" />
			<constructor-arg name="price" value="1000000" />
		</bean>

	</beans>

	
3.获取对象实例

	@Test
	public void test(){
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person = (Person) applicationContext.getBean("person");
		System.out.println(person.getName() + "  " + person.getCar().getName());
		
		//Car benzCar = (Car)applicationContext.getBean("benzCar")
	}
	

3 、 集合注入

Map、Set、List、数组、属性


1.创建实体类
public class Department {  
  
    private String name;  
    private String [] arr;//数组  
    private List<Emp> list;//list集合  
    private Set<Emp> set;//set集合  
    private Map<String,Emp> map;//map集合  
    private Properties pp;//Properties的使用  
	
	//省略get/set方法
	......
}  

2.对applicationContext.xml进行配置

	<?xml version="1.0" encoding="UTF-8"?>
	<beans xmlns="http://www.springframework.org/schema/beans"
		   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		   xsi:schemaLocation="http://www.springframework.org/schema/beans
				http://www.springframework.org/schema/beans/spring-beans.xsd">

		<bean id="department" class="com.b3a4a.domain.Department">
			<property name="name" value="财务部"/>

			<!-- 给数组注入值 -->
			<property name="arr">
				<list>
					<value>小明</value>
					<value>小明</value>
				</list>
			</property>

			<!-- 给list注入值 list 中可以有相当的对象 -->
			<property name="list">
				<list>
					<ref bean="emp2" />
					<ref bean="emp1"/>
				</list>
			</property>

			<!-- 给set注入值 set不能有相同的对象 -->
			<property name="set">
				<set>
					<ref bean="emp1" />
					<ref bean="emp2"/>
				</set>
			</property>

			<!-- 给map注入值 map只有key不一样,就可以装配value -->
			<property name="map">
				<map>
					<entry key="11" value-ref="emp1" />
					<entry key="22" value-ref="emp2"/>
					<entry key="22" value-ref="emp1"/>
				</map>
			</property>

			<!-- 给属性集合配置 -->
			<property name="pp">
				<props>
					<prop key="pp1">abcd</prop>
					<prop key="pp2">hello</prop>
				</props>
			</property>
		</bean>

		<bean id="emp1" class="com.b3a4a.domain.Emp">
			<property name="name" value="北京"/>
			<property name="id" value="1"/>
		</bean>
		<bean id="emp2" class="com.b3a4a.domain.Emp">
			<property name="name" value="天津"/>
			<property name="id" value="2"/>
		</bean>

	</beans>
	
3.通过api获取对应属性

	public void test(){
	
        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");  
        Department department=(Department) ac.getBean("department");  
		
		arr/list/set/map/pp = department.getXXX();
		
		//遍历
	
	}

四 Spring 、注解开发

1.导入相应jar包

	spring-beans-4.2.4.RELEASE.jar
	spring-context-4.2.4.RELEASE.jar
	spring-core-4.2.4.RELEASE.jar
	spring-expression-4.2.4.RELEASE.jar
	commons-logging-1.2.jar
	log4j-1.2.16.jar
	
	
	注意:
	
	spring-aop-4.2.4.RELEASE.jar


2.配置applicationContext.xml(需要在schema约束中引入context命名空间)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
	<context:component-scan base-package="com.b3a4a" />
</beans>

3.在类中使用注解

@Component("loginService")
@Scope("prototype")
public class LoginServiceIMPL implements LoginService {
	
	@Value("cnB3a4a")
	private String username;

	//@Autowired  //默认是按照类型来进行注入
	//@Qualifier("userDao")
	@Resource(name="userDao")
	private UserDAO userDao;

	@Override
	public void add() {
		// System.out.println("userService add.." + name);
		userDao.add();
	}
	
	@PostConstruct
	public void mInit(){}
	
	@PreDestory
	public void mDestory(){}

}


注意:
	如果将注入属性的注解配置在属性上,则可以省略get/set方法


解释说明:

	a)	@Component
	相当于	<bean id="loginService" class="com.b3a4a.annotationtest.LoginServiceIMPL">
	@Component有三个衍生注解功能一样,只是对作用位置进行区分
		@Repository 	用于DAO层
		@Service 		用于service层
		@Controller 	用于表现层
	
	
	b)	@Value	非引用类型
	相当于<property name="username" value="cnB3a4a" />
	
	c)	@Autowired 	@Qualifier  引用类型
		@Autowired	自动装配对象(类型)
		@Qualifier	装配指定名称对象
		@Primary                 提高java优先级

	d)	@Resource(name="名字")
		相当于@Autowired@Qualifier一起配置
	
	e)	@Scope	
	相当于	<bean id="loginService" class="com.b3a4a.annotationtest.LoginServiceIMPL" scope="singleton"> </bean>
	
	@Scope取值有4个
			singleton		单例 代表在spring ioc容器中只有一个Bean实例 (默认的scope)
			prototype	多例 每一次从spring容器中获取时,都会返回一个新的实例
			request 		用在web开发中,将bean对象request.setAttribute()存储到request域中
			session 		用在web开发中,将bean对象session.setAttribute()存储到session域中
			
	f)	@PostConstruct	
	相当于	<bean id="loginService" class="com.b3a4a.annotationtest.LoginServiceIMPL" init-method="mInit" > </bean>

	@PostConstruct注解好多人以为是Spring提供的。其实是Java自己的注解。
	Java中该注解的说明:@PostConstruct该注解被用来修饰一个非静态的void()方法。被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。
	通常我们会是在Spring框架中使用到@PostConstruct注解 该注解的方法在整个Bean初始化中的执行顺序:
	Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)
		
	g)	@PreDestory		
	相当与  <bean id="loginService" class="com.b3a4a.annotationtest.LoginServiceIMPL" destory-method="mDestory" > </bean>
	注意:对于销毁的方法它只对bean的scope=singleton有效。
	@PreDestory修饰的方法会在服务器卸载Servlet的时候运行,并且之后被服务器调用一次,类似于Servlet	中的destory()方法,虽然PreDestory字面意思是在destory之前运行,但是被@PreDestory修饰的方法会在destory方法运行之后运行,在Servlet被彻底卸载之前,PreDestory里的Destory指的是Servlet的销毁,而不是destory()方法。

依赖加载
	@DependsOn    两个Bean的加载顺序 
	@Order   配置文件加载顺序 1 2 3
	@Lazy  类  方法  延迟加载 灾难恢复

5、 Spring全注解配置

配置流程
	

主配置文件SpringConfiguration

	@Configuration    //主配置文件
	@ComponentScan("com.b3a4a")  //扫描包
	@Import(JdbcConfig.class)
	@PropertySource("classpath:jdbcConfig.properties")  //加载properties
	public class SpringConfiguration {

	}
	
辅配置文件JdbcConfig

	public class JdbcConfig {
		@Value("${jdbc.driver}")private String driver;
		@Value("${jdbc.url}")private String url;
		@Value("${jdbc.username}")private String username;
		@Value("${jdbc.password}")private String password;

		@Bean(name="runner")
		@Scope("prototype")
		public QueryRunner createQueryRunner(@Qualifier("mysql_ds") DataSource dataSource){
			return new QueryRunner(dataSource);
		}

		@Bean(name="mysql_ds")
		public DataSource createMysqlDataSource(){
			try {
				ComboPooledDataSource ds = new ComboPooledDataSource();
				ds.setDriverClass(driver);
				ds.setJdbcUrl(url);
				ds.setUser(username);
				ds.setPassword(password);
				return ds;
			}catch (Exception e){
				throw new RuntimeException(e);
			}
		}

		@Bean(name="oracle_ds")
		public DataSource createOracleDataSource(){
			return null;
		}
	}
	
测试用例

    @Test
    public void testFindAllUsers() {
        //1.获取容易
        ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
        //2.得到业务层对象
        UserService service = ac.getBean(UserService.class);
        //3.执行方法
        List<User> users = service.findAllUsers();
        for (User user : users) {
            System.out.println(user);
        }
    }



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值