目录
一、IOC理论推导
UserDao接口
UserDaoImpl实现类
UserService业务接口
UserServiceImpl业务实现类
1、先创建一个UserDao接口
public interface UserDao {
void getUser();
}
2、再写dao实现类
public class UserDaoImpl implements UserDao{
public void getUser() {
System.out.println("默认获取");
}
}
3、写UserService接口
public interface UserService {
void getUser();
}
4、写service实现类
public class UserServiceImpl implements UserService{
private UserDao userDao =new UserDaoImpl();
public void getUser() {
userDao.getUser();
}
}
5、写测试类
@Test
public void test(){
UserService service = new UserServiceImpl();
service.getUser();
}
把UserDao的实现类增加一个(UserDaoMysql)
如果使用UserDaoMysql,我们需要去service里面修改对应的实现。每次变动都要修改大量代码
耦合性太高了
解决方法:(set)
//利用set进行动态实现值的注入 public void setUserDao(UserDao userDao) { this.userDao = userDao; }
测试类
public class MyTest {
public static void main(String[] args) {
// 用户调用的是业务层,dao层不用接触
UserServiceImpl userService = new UserServiceImpl();
userService.setUserDao(new UserMysqlImpl()); //要啥new啥
userService.getUser();
}
}
这种思想,从本质上解决了问题,我们程序员不再去管理对象的创建了,更多的去关注业务的实现,耦合性大大降低,这也就是IOC的原型。
二、hellospring
1、创建hello类
public class Hello {
private String str;
public String getStr() {
return str;
}
//必须有set方法,用set方法注入
public void setStr(String str) {
this.str = str;
}
@Override
public String toString() {
return "Hello{" +
"str='" + str + '\'' +
'}';
}
}
2、编写spring配置文件
<?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">
<!-- 使用spring创建对象,在Spring这些都成问bean
Bean = 对象 new Hello();
id = 变量名
class = new 的对象
property相当于给对象中的属性设置一个值
-->
<bean id="hello" class="com.kum.pojo.Hello">
<property name="str" value="Spring"/>
</bean>
</beans>
3、测试
public class MyTest {
public static void main(String[] args) {
// 获取spring上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//我们的对象现在都在spring中管理,需要就取
Hello hello = (Hello) context.getBean("hello");
System.out.println(hello.toString());
}
}
修改案例一
<?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="userDao" class="com.kun.dao.UserDaoImpl"/>
<bean id="userMysql" class="com.kun.dao.UserMysqlImpl"/>
<bean id="userService" class="com.kun.service.UserServiceImpl">
<property name="userDao" ref="userMysql"/>
</bean>
</beans>
创建
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserServiceImpl userService = (UserServiceImpl) context.getBean("userService");
userService.getUser();
}
}
三、IOC创建对象方式
通过无参构造方法来创建
User类
public class User {
private String name;
public User(){
System.out.println("无参构造");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("name:"+this.name);
}
}
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//在执行getBean的时候, user已经创建好了 , 通过无参构造
User user1 = (User) context.getBean("user");
user1.setName("李明");
user1.show();
User user = new User();
user.setName("小明");
user.show();
}
}
通过有参构造
public class User {
private String name;
public User(String name){
this.name=name;
System.out.println("有参构造");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("name:"+this.name);
}
}
<!-- 第一种 通过下标-->
<bean id="user" class="com.kun.pojo.User">
<constructor-arg index="0" value="带鱼"/>
</bean>
<!-- 第二种 通过类型 不建议使用-->
<bean id="user" class="com.kun.pojo.User">
<constructor-arg type="java.lang.String" value="带鱼"/>
</bean>
<!-- 第三种 通过参数名-->
<bean id="user" class="com.kun.pojo.User">
<constructor-arg name="name" value="带鱼"/>
</bean>
测试
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
User user1 = (User) context.getBean("user");
user1.show();
User user = new User("new对象");
user.show();
}
结论:在配置文件加载的时候。管理的对象就被实例化了。
别名
<!--设置别名:在获取Bean的时候可以使用别名获取-->
<alias name="userT" alias="userNew"/>
Bean里面的配置
<!--bean就是java对象,由Spring创建和管理-->
<!--
id 是bean的标识符,要唯一,如果没有配置id,name就是默认标识符
如果配置id,又配置了name,那么name是别名
name可以设置多个别名,可以用逗号,分号,空格隔开
如果不配置id和name,可以根据applicationContext.getBean(.class)获取对象;
class是bean的全限定名=包名+类名
-->
<bean id="hello" name="hello2 h2,h3;h4" class="com.kun.pojo.Hello">
<property name="name" value="Spring"/>
</bean>
import:团队合作通过import来实现
<import resource="{path}/beans.xml"/>
四、依赖注入
1.构造器注入
Controller
public class FooController {
private final FooService fooService;
@Autowired
public FooController(FooService fooService) {
this.fooService = fooService;
}
}
2.set方式注入
依赖:bean对象的创建依赖于容器
注入:bean对象中的所有属性,由容器来注入
<bean id="address" class="com.kun.pojo.Address">
<property name="address" value="武汉"/>
</bean>
<bean id="student" class="com.kun.pojo.Student">
<!--第一种set注,普通注入-->
<property name="name" value="带鱼"/>
<!-- 第二种 bean注入 ref-->
<property name="address" ref="address"/>
<!-- 第三种 数组注入 -->
<property name="books">
<array>
<value>一本书</value>
<value>二本书</value>
<value>三本书</value>
</array>
</property>
<!-- 4 list注入-->
<property name="hobbies">
<list>
<value>爱好一</value>
<value>爱好二</value>
<value>爱好三</value>
</list>
</property>
<!-- 5 map注入-->
<property name="cards">
<map>
<entry key="身份证" value="123"/>
<entry key="学生证" value="456"/>
</map>
</property>
<!-- 6 Set-->
<property name="games">
<set>
<value>游戏1</value>
<value>游戏2</value>
<value>游戏3</value>
</set>
</property>
<!-- 7 null注入-->
<property name="wife">
<null/>
</property>
<!-- 8 properties注入-->
<property name="info">
<props>
<prop key="学号">123</prop>
<prop key="性别">男</prop>
</props>
</property>
</bean>
测试
import com.kun.pojo.Address;
import com.kun.pojo.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.*;
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Student student = (Student) context.getBean("student");
System.out.println(student.getName()); //1
Address address = student.getAddress(); //2
System.out.println(address.getAddress());
String[] books = student.getBooks(); //3
for (String book : books) {
System.out.println(book);
}
List<String> hobbies = student.getHobbies(); //4
for (String hobby : hobbies) {
System.out.println(hobby);
}
Map<String, String> cards = student.getCards(); //5
Iterator<Map.Entry<String, String>> iterator = cards.entrySet().iterator();
while (iterator.hasNext()){
Map.Entry<String, String> next = iterator.next();
System.out.println("Key="+next.getKey()+"Value="+next.getValue());
}
Set<String> games = student.getGames(); //6
for (String game : games) {
System.out.println(game);
}
System.out.println(student.getWife()); //7
Properties info = student.getInfo(); //8
Iterator<Map.Entry<Object, Object>> iterator1 = info.entrySet().iterator();
while (iterator1.hasNext()){
Map.Entry<Object, Object> next = iterator1.next();
System.out.println("Key="+next.getKey()+"Value="+next.getValue());
}
System.out.println(student.toString());
}
}
p命名和c命名注入
1、P命名空间注入 : 需要在头文件中加入约束文件
导入约束 : xmlns:p="http://www.springframework.org/schema/p"
<!--P(属性: properties)命名空间 , 属性依然要设置set方法-->
<bean id="user" class="com.kun.pojo.User" p:name="狂神" p:age="18"/>
2、c 命名空间注入 : 需要在头文件中加入约束文件
导入约束 : xmlns:c="http://www.springframework.org/schema/c"
<!--C(构造: Constructor)命名空间 , 属性依然要设置set方法-->
<bean id="user" class="com.kun.pojo.User" c:name="狂神" c:age="18"/>发现问题:爆红了,刚才我们没有写有参构造!
解决:把有参构造器加上,这里也能知道,c 就是所谓的构造器注入!
测试:
@Test
public void test02(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
System.out.println(user);
}
3.扩展方式注入
Bean作用域
在Spring中,那些组成应用程序的主体及由Spring IoC容器所管理的对象,被称之为bean。简单地讲,bean就是由IoC容器初始化、装配及管理的对象 .
单例模式(spring默认模式)
原型模式:每次从容器get的,会新生成一个对象
其余的request(请求完失效) session(存在session中) application(全局生效)。这些只在web