Spring简介以及常见的面试题(三)

Spring注解方式实现IOC和DI

1.Spring注解

Spring除了默认的使用xml配置<bean>标签的方式实现配置外,也可以通过注解的方式来实现配置,这种方式效率更高,配置信息清晰,代码在哪对应的配置也在哪儿。

所谓注解就是程序看的提示信息,很多时候都用来作为轻量级配置方式

Spring注解方式实现IOC

a. 导入开发jar包
b. 编写配置文件,并导入context约束

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       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
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
">
    <context:component-scan base-package="cn.tedu"></context:component-scan>
    <context:annotation-config></context:annotation-config>
</beans>

c. 开启包扫描

<context:component-scan base-package="cn.tedu"></context:component-scan>

d. 使用注解注册bean
在配置的包中的额类上使用@Component注解,这个类会自动被注册为bean,使用当前类的class为的class,默认情况下判断类名的第二字母,如果是大写,首字母不变作为id,如果第二个字母是小写,首字母就是小写,默认作为id,也可以自己指定id

e. 可以使bean类实现BeanNameAware接口,并实现其中setBeanName
方法, spring容器会在初始化bean时,调用此方法告知当前bean的id。通过这个方式可以获取 bean的id信息。

@Component("person")//指定标签id不指定类名的首字母小写
public class Person implements BeanNameAware {
    @Override
    public void setBeanName(String name) {
        System.out.println("==="+this.getClass().getName()+"==="+name);
    }
}

f. 注解方式实现工厂注册bean

@Component
public class DogFactory {
    @Bean//可以自己指定id,也可以默认getInstance
    public Dog getInstance(){
        return new Dog("小黑");
    }
}

Spring注解方式实现DI

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:util="http://www.springframework.org/schema/util"
       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
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/util
       http://www.springframework.org/schema/util/spring-util-3.2.xsd
">
    <context:component-scan base-package="cn.tedu.domain"></context:component-scan>
    <!--开启注解方式的DI-->
    <context:annotation-config></context:annotation-config>
    <context:property-placeholder location="my.properties"></context:property-placeholder>
    <util:list id="list">
        <value>aaa</value>
        <value>bbb</value>
        <value>ccc</value>
    </util:list>
    <util:set id="set">
        <value>111</value>
        <value>222</value>
        <value>333</value>
    </util:set>
    <util:map id="map">
        <entry key="k1" value="v1"></entry>
    </util:map>
    <util:properties id="properties">
        <prop key="1"></prop>
    </util:properties>
</beans>

在类的属性中通过@Value注入赋值

@Component
public class Hero {
    //@Value("亚索")
    @Value("${name}")
    private String name;
    //@Value("13")
    @Value("${age}")
    private int age;
    @Value("#{@list}")
    private List<String> list;
    @Value("#{@set}")
    private Set<String> set;
    @Value("#{@map}")
    private Map<String,String> map;
    @Value("#{@properties}")
    private Properties props;

    @Override
    public String toString() {
        return "Hero{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", list=" + list +
                ", set=" + set +
                ", map=" + map +
                ", props=" + props +
                '}';
    }
}

f.使用注解注入自定义bean类型数据

在bean中的属性上通过@Autowired实现自定义bean类型的属性注入代码
@Component
public class Hero {
    @Value("亚索")
    private String name;
    @Value("10")
    private int age;
    @Autowired
    @Qualifier("JMDog")//一旦配置了@Qualifier("JMDog")会按照指定id注入,找到注入,找不到就抛出异常
    //@Resource(name = "JMDog") Java提供的不是Spring提供的,基本不用
    private Dog dog;

    @Override
    public String toString() {
        return "Hero{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", dog=" + dog +
                '}';
    }
}
当Spring容器解析到@Component注解时,创建当前类的bean在Spring容器中进行管理,在创建bean的过程中发现了@Autowired注解,会根据当前bean的类型,寻找Spring中是否存在该类型的bean,如果唯一的bean,直接注入,如果有多个根据id判断,如果有注入,如果没有抛出异常 其次,可以额外配置@Qualifier(“”)注解强制要求按照id进行寻找,找到就注入,找不到就抛出异常,注意@Autowired&@Qualifier(“”)需要配合使用

其他注解

  1. @Scope(value=“prototype”)
    配置修饰类是单例还是多例,Spring默认是单例
//配置bean为多例
@Component
@Scope("prototype")
public class Person {
}
  1. @Lazy
    配置修饰的类的bean采用懒加载机制
    Spring默认在初始化时就通过反射创建对象,并且以键值对的形式存入Spring容器中的Map集合中,在类上配置懒加载的注释,可以在对象使用时再创建,避免内存的浪费
@Component
@Lazy//懒加载
public class Person2 {
    public Person2() {
        System.out.println("person2...init");
    }
}
  1. @PostConstruct
    在bean对应的类中 修饰某个方法 将该方法声明为初始化方法,对象创建之后立即执 行。
@PostConstruct
    public void initConn(){
        System.out.println("初始化数据库连接");
    }
  1. @PreDestroy
    在bean对应的类中 修饰某个方法 将该方法声明为销毁的方法,对象销毁之前调用的方 法。
@PreDestroy
    public void destroyConn(){
        System.out.println("销毁数据库连接");
    }
  1. @Controller @Service @Repository @Component
    这四个注解的功能是完全相同的,都是用来修饰类,将雷声名为Spring管理的bean的
    @Component 一般认为是通用的注解
    @Controller 用在软件分层的控制层,一般用在web层上
    @Service用在业务访问层,service层
    @Repository用在数据访问层(Dao层)

利用Spring IOC DI 实现软件分层解耦

  1. 软件分层思想回顾
    在软件领域有MVC软件设计思想,指导着软件开发过程。在javaee开发领域,javaee 的经典三层架构MVC设计思想的经典应用。而在软件设计思想中,追求的是"高内聚 低 耦合"的目标,利用Spring的IOC 和 DI 可以非常方便的实现这个需求。
//创建不同类的数据的类型实现userDao接口
@Repository("userDao")
public class OracleUserDao implements UserDao{
    @Override
    public void addUser() {
        System.out.println(this+"正在向数据库添加用户");
    }
}
@Repository
public class MySqlUserDao implements UserDao {
    @Override
    public void addUser() {
        System.out.println(this+"正在添加用户");
    }
}
public interface UserDao {
    public void addUser();
}
//service层
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserDao userDao = null;
    @Override
    public void regist() {
        userDao.addUser();
    }
}
public interface UserService {
    public void regist();
}
//web层
@Controller
public class RegistServlet {
    @Autowired
    private UserService service = null;
    public void regist() {
        service.regist();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值