SpringIOC

IOC:

1,简介:

IOC(Inversion of Control 即控制反转)将对象交给容器管理

  1. 谁控制了谁?是容器控制了对象
  2. 控制什么?主要控制了外部资源及生命周期
  3. 由容器帮我们查找并注入依赖的对象,对象只能被动的接收依赖对象,依赖对象的获取被反转了
    在这里插入图片描述
    spring中提供了一种IOC容器,来控制对象的创建,无论是你创建对象,处理对象之间的依赖关系,对象的创建时间还是对象的创建数量,都是spring提供IOC容器上配置对象的信息就可以了

2,作用:

  1. 由IOC容器帮对象找相应的依赖思想并注入,并不是由对象主动去找
  2. 资源集中管理,实现资源的可配置和易管理
  3. 降低了使用资源双方的依赖程度,松耦合

3,Spring容器管理对象:

第一步:maven管理依赖:引入spring核心依赖
    <properties>
        <spring.propety>4.1.7.RELEASE</spring.propety>
    </properties>

    <dependencies>
        <!--spring核心依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.propety}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.propety}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.propety}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>${spring.propety}</version>
        </dependency>
    </dependencies>
第二步:给定容器配置文件:

根标签:

<?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-3.0.xsd">
</beans> 

第三步:IOC容器管理对象:

将userInfo对象交给容器管理:

    <!--使用bean标签来管理对象,id属性必填,用来表示对象,class属性给定对象的全限定名-->
    <bean id="UserInfo" class="xwbspring.Spring.IOC.ObjectUse.UserInfo"/>
第四步:通过容器获取对象
public class IocContest {
    public static void main(String[] args) {
        //获取容器
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("Springcontest.xml");
        //获取对象
        UserInfo userInfo = (UserInfo) context.getBean("UserInfo");
        //getBean():传入的参数必须与XML配置的id相同
        System.out.println(userInfo);
    }
}
运行截图:

在这里插入图片描述

4,Spring中Bean的实例化方式

方法一:基于xml配置形式

<1,通过无参构造实例化:如3中的例子
<2,,通过静态功能方式实例化:

1,创建一个工厂类:
在这里插入图片描述
2,使用工厂的静态方法返回去一个对象:

public class ObjectFactory {
    //静态方法:
    public static UserInfo getBean(){
        return new  UserInfo();
    }
}

3,配置XML文件:

    <!--
    通过静态工厂获取对象
    id属性是给静态工厂获取的对象进行命名
    class属性指向工厂类全限定名
    factory-method属性是工厂类中获取对象的静态方法
    -->
     <bean id="UserInfo1" class="xwbspring.Spring.IOC.IOCDemo.ObjectFactory" factory-method="getBean"/>

❤️,通过普通工厂实例化

1,创建一个工厂类:
在这里插入图片描述
2,使用工厂的普通方法返回一个对象:

public class ObjectFactory {
   //普通方法:
    public UserInfo getUserInfo(){
        return new UserInfo();
    }
}

3,配置XML文件:

    <!--通过普通工厂获取对象 -->
    <bean id="factory" class="xwbspring.Spring.IOC.IOCDemo.ObjectFactory"/>
    <!--创建工厂对象-->
    <bean id="userInfo2" class="xwbspring.Spring.IOC.ObjectUse.UserInfo" factory-bean="factory" factory-method="getUserInfo"/>

方法二:基于注解形式:

1,通过Component注解标记类

@Component(value = "userInfo")
//注解形式类似于配置中bean标签处理, 注解中value参数和bean标签中id是相同的作用
public class UserInfo {
    private String name;
    private String sex;
//todo
}

2,配置XML文件

<!--根标签,注解形式与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: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="xwbspring.Spring.IOC.ObjectUse"/>

</beans>
常见注解:

@Component
@Controller 对Controller层类进行标注(主要接受处理URL)
@Service 对Service层的类进行标注(是进行业务处理)
@Repository 对DAO层实现类进行标注(和数据库打交道的类)
后三个都是Component注解衍生出来,功能是一样,可以互换,为了区分被注解标注的类在不同的业务层,是逻辑更清晰

IOC中属性讲解:
Bean的作用范围@Scope:其@Scope取值可以为singleton:单例对象,默认是单例prototype:多例对象

5,Spring中DI介绍

DI-Dependency Injection:依赖注入
bean对象中需要依赖一些其他组件或者对象,依赖关系由容器在运行时决定
两种方式处理依赖注入:

基于配置形式:

1,有参构造函数注入依赖:

public class User {
    private String name;
    private UserInfo userInfo;

    public User(String name,UserInfo userInfo) {
        this.name = name;
        this.userInfo = userInfo;
    }

相关的XML配置:

    <bean id="user"  class="xwbspring.Spring.IOC.ObjectUse">
        <!--
        通过有参构造函数实例
        constructor-arg:有参构造使用改标签
        name属性:表示是属性名
        value属性:属性赋值,给定字符串参数,给基本引用类型/基本类型赋值
        ref属性:属性赋值,给自定义对象赋值
        -->
        <constructor-arg name="userInfo" ref="userInfo"/>
        <constructor-arg name="name" value="xwb"/>
    </bean>

2,set方法:

public class User {
        private String name;

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

相关的XML配置:

    <bean id="user1" class="xwbspring.Spring.IOC.ObjectUse">
        <property name="name" value="hello"/>
    </bean>

基于注解形式

@Component
public class User {

        @Value("tulun") //针对普通类型(String,int等)的数据
        private String name;

        @Autowired  //注入自定义对象类型
        @Resource  //注入自定义对象类型
        private UserInfo userInfo;

循环依赖的问题:
如果是使用构造函数的方式注入依赖,有可能会无法解决循环依赖的问题
解决办法:
对于会产生循环依赖的问题的这些类可以通过setter方法注入,可以解决循环依赖

6,其他类型:

public class User {
        private String name;
        private UserInfo userInfo;
        //list类型
        private List<String> lists;
        //map类型
        private Map<String,String> maps;

        //set类型
        private Set<String>  sets;


    public void setUserInfo(UserInfo userInfo) {
        this.userInfo = userInfo;
    }

    public void setLists(List <String> lists) {
        this.lists = lists;
    }

    public void setMaps(Map <String, String> maps) {
        this.maps = maps;
    }

    public void setSets(Set <String> sets) {
        this.sets = sets;
    }

相应的XML文件

<property name="lists" >
            <!--list属性注入-->
            <list >
                <value>张三</value>
                <value>李四</value>
            </list>
        </property>
        <property name="maps">
            <!--map类型数据注入-->
            <map>
                <entry key="k1" value="k11"/>
                <entry key="k2" value="k22"/>
            </map>
        </property>
        <property name="sets">
            <!--set类型数据注入-->
            <set>
                <value>set1</value>
                <value>set2</value>
            </set>
        </property>
Python中实现打卡兑换礼物的功能,通常会涉及到以下几个步骤: 1. **数据结构设计**:创建一个数据库或数据结构来存储用户的打卡记录,比如字典或列表,其中每个元素包含用户ID、日期等信息。 ```python users_gifts = {} # 使用字典,key为用户ID,value为打卡记录 ``` 2. **添加打卡功能**:编写函数,当用户调用时,检查用户是否存在并更新打卡次数。例如,可以使用`datetime`库来记录每日打卡时间。 ```python import datetime def check_in(user_id): today = datetime.datetime.now().strftime("%Y-%m-%d") if user_id not in users_gifts: users_gifts[user_id] = {today: 1} else: if today not in users_gifts[user_id]: users_gifts[user_id][today] = 1 else: users_gifts[user_id][today] += 1 ``` 3. **条件判断与兑换规则**:设定一个规则,如连续7天打卡即可兑换一份礼物。可以遍历用户的打卡记录,检查是否符合条件。 ```python def can_exchange(user_id): user_history = users_gifts.get(user_id, {}) consecutive_days = {} for date, count in user_history.items(): if date - consecutive_days.get(date, '') <= datetime.timedelta(days=6): # 连续6天 consecutive_days[date] = count if len(consecutive_days) == 7: # 找到7连日 return True return False ``` 4. **兑换操作**:如果满足兑换条件,可以删除已达到兑换的打卡记录,并通知用户兑换成功。 ```python def redeem_gift(user_id): if can_exchange(user_id): for day, _ in list(users_gifts[user_id].items())[:7]: # 删除前7天的打卡记录 del users_gifts[user_id][day] print(f"恭喜用户{user_id},您的7天连续打卡已成功兑换礼物!") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值