IOC
五·OC创建对象(Spring 创建对象)
Spring 配置
1·构造方式有三种(构造器注入,三种方式之一)
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--第一种,下标赋值 -->
<!--<bean id="user" class="com.ityuan.domain.User">-->
<!-- <constructor-arg index="0" value="彭武源"></constructor-arg>-->
<!--</bean>-->
<!--方式二:通过创建类型,不建议使用,如果有参构造的两个参数都是同一类型,则会造成歧义-->
<!--<bean id="user" class="com.ityuan.domain.User">-->
<!-- <constructor-arg type="java.lang.String" value="彭武源真的帅"></constructor-arg>-->
<!--</bean>-->
<!--三·直接通过参数名来设置-->
<bean id="user" class="com.ityuan.domain.User">
<constructor-arg name="name" value="yuan"/>
</bean>
</beans>
总结:
在配置文件的时候,容器2中管理的对象就已经初始化了
2·配置文件中的import的作用
这个import,一般用于团队开发使用,他可以将对多个配置文件,导入合并为一个。
假设,现在项目中有多个人开发,这三个人负责不同类的开发。不同的类需要注册在不同的bean中
我们可以利用import将所有人的beans,xml合并为一个总的
- 张三
- 李四
- 王五
- applicationContext.xml
<import resource="bean.xml"></import>
<import resource="bean1.xml"></import>
<import resource="bean2.xml"></import>
使用的时候,直接使用总的配置就可以了
六·依赖注入
6.1构造器注入
前面已经说了
6.2 Set方式注入
①创建类
public class Student {
private String name;
private Address address;
private String[] books;
private List<String> hobbys;
private Map<String,String> card;
private Set<String> games;
private String wife;
private Properties info;
//自己加上getset方法和tostring方法
②创建复杂类
public class Address {
private String address;
public String getName() {
return address;
}
public void setName(String name) {
this.address = name;
}
@Override
public String toString() {
return "Address{" +
"address='" + address + '\'' +
'}';
}
}
③配置bean.xml
<bean id="student" class="com.ityuan.domain.Student">
<!-- 第一种普通值的注入 value-->
<property name="name" value="pwy"></property>
<!-- 第二种,bean注入-->
<property name="address" ref="address"></property>
<!--数组-->
<property name="books">
<array>
<value>西游记</value>
<value>三国演义</value>
<value>红楼梦</value>
<value>水浒传</value>
</array>
</property>
<!-- list -->
<property name="hobbys">
<list>
<value>符馨芳</value>
<value>向敏</value>
<value>beautiful girl</value>
</list>
</property>
<!--map-->
<property name="card">
<map>
<entry key="身份证" value="4331271996061200xx"></entry>
<entry key="银行卡" value="666666666666666666"></entry>
</map>
</property>
<!--Set -->
<property name="games">
<set >
<value>LOL</value>
<value>COC</value>
<value>BOB</value>
</set>
</property>
<!--null-->
<property name="wife">
<null></null>
</property>
<!-- Properties -->
<property name="info">
<props>
<prop key="学号" >20153662</prop>
<prop key="性别" >男</prop>
</props>
</property>
</bean>
</beans>
④测试类
public class MyClass {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Student student = (Student) context.getBean("student");
System.out.println(student.getName());
System.out.println(Arrays.toString(student.getBooks()));//单独输出四大名著
System.out.println( student.toString());
}
}
6.3 扩展方式注入
扩展方式注入:(注意点)两种方式不能直接使用,要导入约束
1·创建一个User类,里面有两个属性(age,name),用①,②两种方式给他们注入值
public class User {
private String name;
private int age;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
①p命名空间的xml注入(对应着set注入,因此User类中需要GetSet方法)
xmlns:p=“http://www.springframework.org/schema/p”
<!--p命名空间 对应着set方式注入 可以直接注入属性的值:property-->
<bean id="userp" class="com.ityuan.domain.User" p:name="wuyaun" p:age="24"></bean>
②c命名空间的xml注入(User类中要有有参和无参两个构造器,不然c命名空间会报错)
xmlns:c=“http://www.springframework.org/schema/c”
<!--c命名空间 对应着构造器方式注入 -->
<bean id="userc" class="com.ityuan.domain.User" c:name="wuhao" c:age="18" ></bean>
完整的beans
<?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"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--p命名空间 对应着set方式注入 可以直接注入属性的值:property-->
<bean id="username" class="com.ityuan.domain.User" p:name="wuyaun" p:age="24"></bean>
<!--c命名空间 对应着构造器方式注入 -->
<bean id="userage" class="com.ityuan.domain.User" c:name="wuhao" c:age="18" ></bean>
3.编写测试类MyTestUser
public class MyClassUser {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
User username =(User) context.getBean("userp",User.class);//p命名空间
System.out.println(username);
}
}
public class MyClassUser {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
User username =(User) context.getBean("userc",User.class);//c命名空间
System.out.println(username);
}
}
6.4 bean的作用域
1` singleton(单例模式)
拿出两个对象,两个对象都是单利出来的故此验证如下
User userp2 =(User) context.getBean("userp",User.class);
User userp1 =(User) context.getBean("userp",User.class);
// System.out.println(userc);
// System.out.println(userp);
System.out.println(userp1 == userp2);
//userp和userp1是取出来的两个不同对象,但他们都是由userp单例出来的,故此结果为true
2·prototype(原型对象)
原型模式:每次从容器中get的时候,都会产生一个新对象
<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>
3·其余的request,session,application这些个只能在web开发中使用
七·bean的自动装配
在spring中有三种装配的方式
7.1测试
环境搭建
一个人有两个宠物
7.2byName自动装配
<bean id="cat" class="com.ityuan.pojo.Cat"></bean>
<bean id="dog" class="com.ityuan.pojo.Dog"></bean>
<!--byName会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean id-->
<bean id="people" class="com.ityuan.pojo.People" autowire="byName">
<property name="name" value="张纾荣"></property>
</bean>
7.3byType自动装配
<bean id="cat666" class="com.ityuan.pojo.Cat"></bean>//只关注同类型
<bean class="com.ityuan.pojo.Dog"></bean>//不要id
<!--byType会自动在容器上下文中查找,和自己对象类型相同的bean-->
<bean id="people" class="com.ityuan.pojo.People" autowire="byType">
<property name="name" value="张纾荣"></property>
</bean>
使用这个的时候,只需要关注同类型即可,如果类中有两个相同的类型则方法失效
小结:
-
byName的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法一致
-
byType的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性类型一致
7·4使用注解实现自动装配
要使用注解须知:
1·导入约束
xmlns:context=“http://www.springframework.org/schema/context”
2·配置注解需要的支持
< context:annotation-config />[重要]
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
@Autowired
直接在属性上使用即可
也可以再set方法上面使用,不过多用在属性上
用了这个注解甚至都不用在写set方法了,前提是你这个自动装配的属性在IOC中存在,且符合名字byName
科普:
@Nullable 字段标记了这个注解,说明这个字段可以为null;
@Autowired(required = false)
如果定义显示了Autowired 的required属性为false,说明这个对象可以为null,否则不允许为空
如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,搭配@Qualifer(value=“xxx”)去配合@Autowired使用,指定一个唯一的bean对象注入
@Resource注解
@Autowired 和@Resource的区别
- 都是用来自动装配的,都可以放在属性字段上
- @Autowired 通过byname的方式实现,而且必须要求对象存在 【常用】
- @Resource 默认通过byName方式实现,如果找不到名字,则通过byType方式实现。若均找不到,则报错 【常用】
- 执行顺序不同:@Autowired 通过byType的方式实现
八·使用注解开发
在Spring4之后要是用注解开发,必须保证Aop的包导入了
使用注解开发需要导入context约束,增加注解的支持
1.bean
2.属性如何注入
@Value("wuhao")//相当于
public String name;
3.衍生的注解
@Component 有几个衍生注解 ,我们在web开发的时候,会按照mvc三层架构分层
- Dao [ @Repository ]
- service [ @Service ]
- controller [ @controller ]
以上四个注解功能是一样的,都是代表将某个类注册到Spring中,装配bean
4·自动装配
5·作用域
6·小结
- xml更加万能,适合于任何场合!维护简单方便
- 注解,不是自己的类使用不了维护相对复杂
7·xml与注解的最佳实践
xml只负责管理bean,注入的话交给注解去做
我们在使用的过程中,我们只需要注意一个问题,必须让注解生效,就需要开启注解的支持
<!--指定要扫描的包,这个报下的注解机会生效-->
<context:component-scan base-package="com.ityuan.pojo"></context:component-scan>
<context:annotation-config/>
九·使用java的方式配置Spring
我们现在完全不使用Spring的xml配置了,全权交给Java来做