Spring——IOC
一、IOC:控制反转;(DI:依赖注入)
1)控制反转:将创建对象、属性值的方式进行反转,从new、setXxx()反转为SpringIOC容器getBean();
2)依赖注入:将属性值注入给了属性;将属性注入给了bean;将bean注入给了IOC容器;
二、核心依赖:
1)Spring AOP:开发aop;
2)Spring Beans:处理bean;//<bean>
3)Spring Context :处理spring上下文;//<context>
4)Spring Core:spring核心,IOC;
5)Spring Expression:spring表达式;
6)Commons Logging:日志;
三、IOC使用示例:
1)导入依赖:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.12</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.8.Release</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.2.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.2.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.2.8.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>4.2.8.RELEASE</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.2</version> </dependency>
2)配置spring-context.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="user" class="com.qf.entity.User"> <property name="id" value="01" /> <property name="name" value="zs" /> <property name="age" value="17" /> </bean> </beans>
3)测试:
public class SpringTest { public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application-context.xml"); User user = applicationContext.getBean(User.class); System.out.println(user); //User{id=1, name='zs', age=17} } }
四、配置bean的三种方式:
1)构造方法:
1、scope="singleton":单例;默认为单例;初始化时创建对象;
scope="prototype":多例;每次调用都创建对象;
2、lazy-init="true":延迟加载,只有使用的时候加载;
3、init-method:初始化对象调用方法;
4、destroy-method:销毁对象调用放过发;
5、id:唯一标识,不可以有特殊字符;
6、name:和id一样,但可以有特殊字符,且可以用,逗号隔开设置多个;
PS:如果name和id都没有,则默认给一个类的全类名;也不可以name/id同时存在;
<bean scope="singleton" lazy-init="true" init-method="" destroy-method=""></bean>
2)工厂方法:
1、静态工厂:
<bean name="userFactory" class="com.qf.util.UserFactory" factory-method="getUser" />
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class UserFactory{ public static User getUser(){ System.out.println("获取一个User对象"); return new User(); } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?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 name="userFactory" class="com.qf.util.UserFactory" factory-method="getUser" /> </beans>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class SpringTest { public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application-context.xml"); User user = (User) applicationContext.getBean("userFactory"); System.out.println(user); } }
2、非静态工厂:
<bean id="userFactory" class="com.qf.util.UserFactory" ></bean> <bean id="user" factory-bean="userFactory" factory-method="getUser"></bean>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class UserFactory{ public User getUser(){ System.out.println("获取一个User对象"); return new User(); } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?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="userFactory" class="com.qf.util.UserFactory" ></bean> <bean id="user" factory-bean="userFactory" factory-method="getUser"></bean> </beans>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class SpringTest { public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application-context.xml"); User user = applicationContext.getBean(User.class); System.out.println(user); } }
五、bean属性注入:
1)set方法注入:
1、基本类型:value;
2、引用类型:ref;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?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 name="user" class="com.qf.entity.User"> <property name="id" value="01"></property> <property name="name" value="zs"></property> <property name="age" value="12"></property> <property name="userDetail" ref="userDetail"></property> </bean> <bean name="userDetail" class="com.qf.entity.UserDetail"> <property name="uId" value="01"></property> <property name="balance" value="100"></property> </bean> </beans>
2)构造函数注入:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class User { private Long id; private String name; private Integer age; private UserDetail userDetail; public User() { } public User(Long id, String name, Integer age, UserDetail userDetail) { this.id = id; this.name = name; this.age = age; this.userDetail = userDetail; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public UserDetail getUserDetail() { return userDetail; } public void setUserDetail(UserDetail userDetail) { this.userDetail = userDetail; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", userDetail=" + userDetail + '}'; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?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 name="user" class="com.qf.entity.User"> <constructor-arg name="id" value="01"></constructor-arg> <constructor-arg name="name" value="zs"></constructor-arg> <constructor-arg name="age" value="12"></constructor-arg> <constructor-arg name="userDetail" ref="userDetail"></constructor-arg> </bean> <bean name="userDetail" class="com.qf.entity.UserDetail"> <property name="uId" value="01"></property> <property name="balance" value="100"></property> </bean> </beans>
PS:如果构造函数有多个参数属性时,可以用index标识传入的位置和用type标识参数类型;
<bean name="user" class="com.qf.entity.User"> <constructor-arg name="id" value="01" index="0" type="java.lang.Long"></constructor-arg> <constructor-arg name="name" value="zs" index="1"></constructor-arg> <constructor-arg name="age" value="12" index="2"></constructor-arg> <constructor-arg name="userDetail" ref="userDetail" index="3"></constructor-arg> </bean>
3)p:命名空间注入:使用的是set方法;
1、简单类型:p:属性名="值"
2、引用类型:P:属性名-ref="bean名称"
使用方法:beans中引入:xmlns:p="http://www.springframework.org/schema/p"
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean name="user" class="com.qf.entity.User" p:id="01" p:name="zs" p:age="12" p:userDetail-ref="userDetail"></bean> <bean name="userDetail" class="com.qf.entity.UserDetail"> <property name="uId" value="01"></property> <property name="balance" value="100"></property> </bean> </beans>
4)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean name="user" class="com.qf.entity.User"> <property name="id" value="01"></property> <property name="name" value="zs"></property> <property name="age" value="12"></property> </bean> <bean name="userDetail" class="com.qf.entity.UserDetail"> <property name="uId" value="01"></property> <property name="balance" value="100"></property> </bean> <bean name="user2" class="com.qf.entity.User" p:userDetail-ref="userDetail"> <property name="id" value="#{user.id}"></property> <property name="name" value="#{user.name}"></property> <property name="age" value="#{user.age}"></property> <property name="userDetail" value="#{userDetail}"></property> </bean> </beans>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class SpringTest { public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application-context.xml"); User user2 = applicationContext.getBean("user2",User.class); System.out.println(user2); } }
5)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class Car { private String name; private String color; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } @Override public String toString() { return "Car{" + "name='" + name + '\'' + ", color='" + color + '\'' + '}'; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class TestCollection { private Object[] arrs; private List list; private Map map; private Properties properties; public Object[] getArrs() { return arrs; } public void setArrs(Object[] arrs) { this.arrs = arrs; } public List getList() { return list; } public void setList(List list) { this.list = list; } public Map getMap() { return map; } public void setMap(Map map) { this.map = map; } public Properties getProperties() { return properties; } public void setProperties(Properties properties) { this.properties = properties; } @Override public String toString() { return "TestCollection{" + "arrs=" + Arrays.toString(arrs) + ", list=" + list + ", map=" + map + ", properties=" + properties + '}'; } }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean name="car" class="com.qf.entity.Car"> <property name="name" value="保时捷"/> <property name="color" value="红色"/> </bean> <bean name="testColl" class="com.qf.entity.TestCollection"> <!-- 数组变量注入 --> <property name="arrs"> <list> <value>数组1</value> <!--引入其他类型--> <ref bean="car"/> </list> </property> <!-- 集合变量赋值--> <property name="list"> <list> <value>集合1</value> <!--集合变量内部包含集合--> <list> <value>集合中的集合1</value> <value>集合中的集合2</value> <value>集合中的集合3</value> </list> <ref bean="car"/> </list> </property> <!--map赋值 --> <property name="map"> <map> <entry key="car" value-ref="car"/> <entry key="name" value="保时捷"/> <entry key="age" value="11"/> </map> </property> <!-- properties赋值 --> <property name="properties"> <props> <prop key="name">pro1</prop> <prop key="age">111</prop> </props> </property> </bean> </beans>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class SpringTest { public static void main(String[] args) { ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application-context.xml"); TestCollection testColl = applicationContext.getBean("testColl", TestCollection.class); System.out.println(testColl); } }
六、构建应用上下文:
1)FileSystemXmlApplicationContext:从硬盘绝对路径下获取;
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("D:\\applicationContext-bean.xml");
2)ClassPathXmlApplicationContext:从类路径下获取;
普通项目:src;maven项目:resources;
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application-context.xml");
七、注解配置:
1)配置注解扫描器:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?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.qf.entity"></context:component-scan> </beans>
2)类注解:
1、@Component(""):
用表标记需要注入的bean,等效于配置xml<bean id="" class="">:
不指定name则按类型类名匹配;
@Repository("");dao层;
@Service("");Service层;
@Controller("");Controller层;
2、指定是单例还是多例;
@Scope(scopeName="singleton")
@Scope(scopeName="prototype")
2)属性/方法注解:
1、给属性赋值:
@Value("name值") private String name;
2、给方法参数赋值:
@Value("name值") public void setName(String name) { this.name = name; }
3、@PostConstruct:初始化方法;@PreDestroy:销毁方法;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
@PostConstruct public void init(){ System.out.println("初始化方法"); } @PreDestroy public void destroy(){ System.out.println("销毁方法"); }
3)自动装配注解:
1、@Autowired:默认按类型指定;
//如果装配的是接口,自动会去找实现类;但是实现类有两个,就需要@Qualifier()指定;
2、@Qualifier(“类名”):
@Scope(scopeName = "prototype") @Component("User") public class User { @Value("name值") private String name; private Integer age; @Autowired @Qualifier("userDetail02") //指定实现类 private UserDetail userDetail; //自动装配
3、@Resource:等同于上面两个一起;
@Resource("name") == @Autowired + @Qualifier("name")
@Resource("userDetail02") private UserDetail userDetail; //自动装配