java · 2021年3月13日 0

spring


spring

IOC创建对象

1.使用无参构造创建对象,默认

2.使用有参构造对象:

1.下标赋值:

<!--第-种,下标赋值 !-->
<bean id="user" class="com. kuang. pojo.User">
< constructor-arg  index= "0" value="哈哈哈"/>
</bean>

2.参数名

<!--第三种, 直接通过参数名来设置-->
<bean id="user" class="com. kuang. pojo .User">
<constructor-arg name="name" value="哈哈哈"/>
</bean>

spring配置

1、别名

 <!--别名,如果添加了别名,我们也可以使用别名获取到这个对象-->
 <alias name="user" alias="userNew"/>

2、Bean的配置

<!--
id:bean的唯一标识符,也就是相当于我们学的对象名
class : bean 对象所对应的全限定名:包名+类型
name :也是别名,而且name可以同时取多个别名 -->
<bean id="userT" class="com.cuoni.pojo.User" name= "user2 u2,u3;u4">
<property name="name" value=" 西部开源" />
</bean>

3、import

这个import,一般用于团队开发使用,他可以将多个配置文件,导入合并为一-个
假设,现在项目中有多个人开发,这三个人复制不同的类开发,不同的类需要注册在不同的bean中,我们可以利
用import将所有人的beans.xml合并为一个总的!
●张三
●李四
●applicationContext.xml

 <import resource="beans.xml"/>
 <import resource="beans2.xml"/>
 <import resource="beans3.xml"/>

使用的时候,直接使用总的配置就可以了

依赖注入

1、构造器注入

2、set方式注入

  • 依赖注入
    • 依赖:bean对象的创建依赖于容器
    • 注入:bean中的所有属性,由容器来注入

环境搭建:

1、复杂类型

public class Address {
    private String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

 

2、真实测试对象

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;
}

3、beans.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="address" class="com.cuoni.pojo.Address">
        <property name="address" value="湖北"/>
    </bean>
    <bean id="student" class="com.cuoni.pojo.Student">
        <!-- 第一种,普通值注入 -->
        <property name="name" value="哈哈哈"/>
        <!-- 第二种,Bean注入 -->
        <property name="address" ref="address"/>
        <!-- 第三种,数组注入 -->
        <property name="books">
            <array>
                <value>金瓶梅</value>
                <value>西游记</value>
                <value>三国演义</value>
                <value>水浒传</value>
            </array>
        </property>
        <!-- 第四种,list注入 -->
        <property name="hobbys">
            <list>
                <value>唱</value>
                <value>跳</value>
                <value>rap</value>
                <value>篮球</value>
            </list>
        </property>
        <!-- 第五种,map注入 -->
        <property name="card">
            <map>
                <entry key="身份证" value="123456789874562145"/>
                <entry key="学生证" value="14224588452754155245"/>
                <entry key="银行卡" value="6214975402158661"/>
            </map>
        </property>
        <!-- 第六种,set注入 -->
        <property name="games">
            <set>
                <value>吃饭</value>
                <value>睡觉</value>
                <value>打豆豆</value>
            </set>
        </property>
        <!-- 第七种,null注入 -->
        <property name="wife">
            <null/>
        </property>
        <!-- 第八种,Properties注入 -->
        <property name="info">
            <props>
                <prop key="学号">10210417777</prop>
                <prop key="姓名">夏智</prop>
                <prop key="性别r">男</prop>
                <prop key="物种">人</prop>
            </props>
        </property>
    </bean>
</beans>

4、测试类

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
        Student student=(Student) context.getBean("student");
        System.out.println(student.toString());
    }
}

 

 

3、拓展方式注入

1、userbeans.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"
       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命名空间注入,可以直接注入属性的值: property-->
    <bean id="user" class="com.cuoni.pojo.User" p:name="夏智" p:age="20"/>
    <!--c命名空间注入,通过构造器注入: construct-args-->
    <bean id="user2" class="com.cuoni.pojo.User" c:name="哈哈" c:age="22"/>
</beans>

2、测试:

  @Test
    public void yest2(){
     ApplicationContext context=   new ClassPathXmlApplicationContext("userbeans.xml");
     User user=context.getBean("user2",User.class);
        System.out.println(user);
    }

注意: p命名和c命名空间不能直接使用,需要导入xml约束!

 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:c="http://www.springframework.org/schema/c"

bean的作用域

范围 Description
singleton (默认)将单个 bean 定义范围到每个 Spring IoC 容器的单个对象实例。
prototype 将单个 bean 定义范围到任何数量的对象实例。每次从容器中get的时候,都会产生一个新对象!
request 将单个 bean 定义范围到单个 HTTP 请求的生命周期。也就是说,每个 HTTP 请求都有自己的 bean 实例,该实例是在单个 bean 定义背面创建的。仅在 Web 感知 Spring 的上下文中有效。ApplicationContext
session 将单个 bean 定义范围到 HTTP 的生命周期。仅在 Web 感知 Spring 的上下文中有效。Session``ApplicationContext
application 将单个 bean 定义范围到 的生命周期。仅在 Web 感知 Spring 的上下文中有效。ServletContext``ApplicationContext
websocket 将单个 bean 定义范围到 的生命周期。仅在 Web 感知 Spring 的上下文中有效。WebSocket``ApplicationContext

1.单例模式(Spring默认机制)

<bean id="user2" class="com.cuoni.pojo.User" c:age="18" c:name="哈哈哈"
scope="singleton"/>

2.原型模式:每次从容器中get的时候,都会产生一个新对象 !

<bean id="accountService" class="com.something.DefaultAccountService"
scope="prototype"/>

3.其余的request、session、application. 这些个只能在web开发中使用到!

####

Bean的自动装配

  • 自动装配是Spring满足bean依赖一 种方式!
  • Spring会在. 上下文中自动寻找,并自动给bean装配属性! 在Spring中有三种装配的方式
    1.在xml中显示的配置
    2.在java中显示配置
    3.隐式的自动装配bean

1、测试

环境搭建:一个人有两只宠物,猫和狗

2、ByName自动装配

 <!--
    byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanid!
  -->
        <bean id="people" class="com.cuoni.pojo.People" autowire="byName">
            <property name="name" value="夏智"/>

3、ByType自动装配

    <bean  class="com.cuoni.pojo.Cat"/>
    <bean  class="com.cuoni.pojo.Dog"/>
    <!--
    byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean!
    -->
        <bean id="people" class="com.cuoni.pojo.People" autowire="byType">
            <property name="name" value="夏智"/>
        </bean>

小结: .
●byname的时候,需要保证所有bean的id唯一, 并且这个bean需要和自动注入的属性的set方法的值一致!
●bytype的时候,需要保证所有bean的class唯一, 并且这个bean需要和自动注入的属性的类型一致!

4、使用注解实现自动装配

jdk1.5支持的注解,Spring2.5就支持注解了

要使用注解须知: .
1.导入约束: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方式上使用!
使用Autowired我们可以不用编写Set方法了,前提是你这个自动装配的属性在IOC (Spring) 容器中存在,且符
合名字byname!

科普:

@Nullable  字段标记了这个注解,说明这个字段可以为null;
pub1ic @interface Autowired {
boolean required() default true;
}

测试代码

public class People {
    //如果显示定义了Autowi red的requi red属性为false, 说明这个对象可以为nu11,否则不允许为空
    @Autowired(required=false)
    private Cat cat;
    @Autowired
    private Dog dog;
    private String name;
}

如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解[@Autowired]完成的时候、我们可以
使用@Qualifier(value=”xxx”)去配置@Autowired的使用,指定一个唯一 -的bean对象注入!

  • 小结:
    @Resource和@ Autowired的区别: .
    都是用来自动装配的,都可以放在属性字段上
    @ Autowired通过bytype的方式实现,而且要求这个对象必须存在
    @Resource 默认通过byname的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错!

使用注解开发

1、bean

 

2、属性如何注入

//@Component组件,相当于<bean id="user" class="com.cuoni.pojo.User"/>
@Component
public class User {
    @Value("哈哈哈")
    public String name;
}

3、衍生的注解

@Component有几个衍生注解,我们在web开发中,会按照mvc三层架构分层!

  • dao【@Repository】
  • service【@Service】
  • controller【@Controller】

这四个注解功能都是一样的, 都是代表将某个类注册到Spring中,装配Bean

4、自动装配置

@Autowired :自动装配通过类型。名字
  如果Autowi red不能唯一自 动装配上属性,则需要通过@Qualifier(value="xxx")
@Nu11able
字段标记了这个注解,说明这个字段可以为nu11;
@Resource : 自动装配通过名字。类型。

 

5、作用域

@Component
@Scope("prototype")//原型模式
public class User {
    @Value("哈哈哈")
    public String name;
}

6、小结

xml与注解:
xml更加万能,适用于任何场合!维护简单方便.
注解不是自己类使用不了,维护相对复杂!
xml与注解最佳实践:
xml用来管理bean;
注解只负责完成属性的注入; .

我们在使用过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持

<!-- 指定要扫描的包,这个包下的注解就会生效 -->
<context:component-scan base-package="com.cuoni"/>
<context:annotation-config/>

使用java的方式配置spring

我们现在要完全不使用Spring的xml配置了,全权交给Java来做!
JavaConfig是Spring的一个子项目,在Spring 4之后,它成为了一个核心功能!

实体类:

@Component
public class User {
    @Value("夏智")
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

配置类:

//这个也会Spring容器托管,注册到容器中,因为他本米就是一 个@Component,@Configuration代表这是一个配置类,就租我们之前看的beans.xml
@Configuration
@ComponentScan("com.cuoni")
public class CuoniConfig {
    //注册一个bean ,就相当 于我们之前写的一个bean标签
    //这个方法的名字,就相当Fbean标签中的d属性
    //这个方法的返回值,就相当Fbean标签中的class属性
    @Bean
    public User getUser(){
        return new User();//就是返回要注入到bean的对象!
    }
}

测试类:

public class MyTest {
    public static void main(String[] args) {
        //如果完全使用J配置类方式去做,我们就只能通过AnnotationConfig上下文来获取容器,通过配置类的cLass对象加载!
        ApplicationContext context=new AnnotationConfigApplicationContext(CuoniConfig.class);
        User user=context.getBean("user",User.class);
        System.out.println(user.getName());
    }
}

代理模式

1、静态代理

角色分析:
●抽象角色: -般会使用接口或者抽象类来解决
●真实角色:被代理的角色
●代理角色:代理真实角色,代理真实角色后,我们一般会做- -些附属操作
●客户:访问代理对象的人!

代码步骤

1、接口

public interface Rent {
    public void rent();

2、真实角色

public class Host implements Rent{
    public void rent() {
        System.out.println("房东要出租房子");
    }
}

3、代理角色

public class Proxy implements Rent{
    private Host host;

    public Proxy() {
    }

    public Proxy(Host host) {
        this.host = host;
    }

    public void rent() {
        seeHouse();
        host.rent();
        hetong();
        fare();
    }
    public void seeHouse(){
        System.out.println("中介带你看房");
    }
    public void fare(){
        System.out.println("中介收中介费");
    }
    public void hetong(){
        System.out.println("中介带你签合同");
    }
}

4、客户端访问代理角色

public class Client {
    public static void main(String[] args) {
        Host host=new Host();
//        host.rent();
        Proxy proxy=new Proxy(host);
        proxy.rent();
    }
}

 

代理模式的好处:
●可以使真实角色的操作更加纯粹!不用去关注一 些公共的业务
●公共也就就交给代理角色!实现了业务的分工!
●公共业务发生扩展的时候,方便集中管理!
缺点:
●一个真实角色就会产生一个代理角色;代码量会翻倍开发效率会变低~