Sping

Spring

  • ==Spring的IOC/DI==

  • ==Spring的AOP==

  • ==AOP的具体应用,事务管理==

  • ==IOC/DI的具体应用,整合Mybatis==S

1.1IOC

IOC:控制反转,控制反转的是对象的创建权

DI:依赖注入,绑定对象与对象之间的依赖关系

1.1.1bean的配置
    <!--bean标签标示配置bean
    id属性标示给bean起名字
    class属性表示给bean定义类型
    name标识配置bean的多个别名
    scope表示bean的作用范围,singleton默认为单例(创建出的两个bean地址相同),prototype为非单例
-->
    <bean id="bookService" name="service,bookService2" class="com.example.service.impl.BookServiceImpl"
scope="prototype">
        <!--配置server与dao的关系-->
        <!--property标签表示配置当前bean的属性
                name属性表示配置哪一个具体的属性
                ref属性表示参照哪一个bean
        -->
        <property name="bookDao" ref="bookDao"/>
    </bean>
1.1.2bean的实例化(创建)
1.构造方法:
public interface BookDao {
    public void save();
}
​
public class BookDaoImpl implements BookDao {‘
//可以提供无参的构造方法,因为每一个类默认都会提供一个无参构造函数
    public BookDaoImpl() {
        System.out.println("book dao constructor is running ....");
    }
    public void save() {
        System.out.println("book dao save ...");
    }
}
​
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
​
 ApplicationContext ctx = new 
     ClassPathXmlApplicationContext("applicationContext.xml");
 BookDao bookDao = (BookDao) ctx.getBean("bookDao");
 bookDao.save();
2.静态工厂:
//静态工厂创建对象
public class OrderDaoFactory {
    public static OrderDao getOrderDao(){
        return new OrderDaoImpl();
    }
}
​
//通过静态工厂创建对象
OrderDao orderDao = OrderDaoFactory.getOrderDao();
orderDao.save();
​
spring实例化静态工厂:
<bean id="orderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOrderDao"/>
​
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
OrderDao orderDao = (OrderDao) ctx.getBean("orderDao");
orderDao.save();
3.实例化工厂:
//和静态工厂的工厂类不一样的地方是方法不是静态方法
public class UserDaoFactory {
    public UserDao getUserDao(){
        return new UserDaoImpl();
    }
}
​
//创建实例工厂对象
UserDaoFactory userDaoFactory = new UserDaoFactory();
UserDao userDao = userDaoFactory.getUserDao();
userDao.save();
​
spring实现实例化工厂:
<bean id="userFactory" class="com.itheima.factory.UserDaoFactory"/>
<bean id="userDao" factory-bean="userFactory" factory-method="getUserDao" />
4.FactoryBean:
//实现FactoryBean接口
public class EmpDaoFactory implements FactoryBean {
    //代替原始实例工厂中创建对象的方法,返回实例化bean对象
    @Override
    public Object getObject() throws Exception {
        return new EmpDaoImpl();
    }
​
    //返回所创建类的Class对象
    @Override
    public Class<?> getObjectType() {
        return EmpDao.class;
    }
​
    //创建bean是否单例
    @Override
    public boolean isSingleton() {
        return FactoryBean.super.isSingleton();
    }
}
<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"/>
1.1.3.bean的生命周期

bean对象从创建到销毁的整体过程(init==>destory)

public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ...");
    }
    //表示bean初始化对应的操作
    public void init(){
        System.out.println("init...");
    }
    //表示bean销毁前对应的操作
    public void destory(){
        System.out.println("destory...");
    }
​
}
​
public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
    private BookDao bookDao;
​
    public void setBookDao(BookDao bookDao) {
        System.out.println("set .....");
        this.bookDao = bookDao;
    }
​
    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
​
    public void destroy() throws Exception {
        System.out.println("service destroy");
    }
​
    //属性配置后执行
    public void afterPropertiesSet() throws Exception {
        System.out.println("service init");
    }
}
//在配置文件中的bean标签中添加init-method和destroy-method属性
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"/>
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
    <property name="bookDao" ref="bookDao"/>
</bean>
​
运行结果:
init... //先bean的初始化
set ..... //bean的注入
service init //业务操作
book service save ...
book dao save ...
service destroy //业务结束
destory... //bean销毁

1.2DI

1.2.1依赖注入
1.setter注入:
public class BookServiceImpl implements BookService {
    //引用数据类型
    private BookDao bookDao;
    //简单数据类型
    private Integer age;
​
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
​
    public void setAge(Integer age) {
        this.age = age;
    }
​
    @Override
    public void save() {
        System.out.println("book service save");
        bookDao.save();
        System.out.println(age);
    }
}
//使用property标签和ref,value属性注入
<bean id="bookDao" class="com.example.dao.impl.BookDaoImpl"></bean>
<bean id="bookService" class="com.example.service.impl.BookServiceImpl">
    <property name="bookDao" ref="bookDao"></property>
    <property name="age" value="10"></property>
</bean>
​
2.构造器注入:
public class UserServiceImpl implements UserService {
    private UserDao userDao;
    private Integer age;
​
    public UserServiceImpl(UserDao userDao,Integer age){
        this.userDao = userDao;
        this.age = age;
    }
​
    @Override
    public void save() {
        System.out.println("user service save");
        userDao.save();
        System.out.println(age);
    }
}
//使用constructor-arg标签和ref,value属性注入
<bean id="userDao" class="com.example.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.example.service.impl.UserServiceImpl">
    <constructor-arg name="userDao" ref="userDao"></constructor-arg>
    <constructor-arg name="age" value="10"></constructor-arg>
</bean>
​
构造器其他注入方式(按照实际情况使用):
//方式一:删除name属性,添加type属性,按照类型注入
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
    <constructor-arg type="int" value="10"/>
    <constructor-arg type="java.lang.String" value="mysql"/>
</bean>
//方式二:删除type属性,添加index属性,按照索引下标注入,下标从0开始
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
    <constructor-arg index="1" value="100"/>
    <constructor-arg index="0" value="mysql"/>
</bean>
​
注:如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入
​
3.自动配置:
自动装配用于引用类型依赖注入,不能对简单类型进行操作
需要注入属性的类中对应属性的setter方法不能省略
自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效
按照类型注入:
<bean class="com.itheima.dao.impl.BookDaoImpl"/>
<!--autowire属性:开启自动装配,通常使用按类型装配-->
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" autowire="byType"/>
按照名称注入:
<bean class="com.itheima.dao.impl.BookDaoImpl"/>
<!--autowire属性:开启自动装配,通常使用按类型装配-->
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" autowire="byName"/>
​
4.集合注入:
public class BookDaoImpl implements BookDao {
​
    private int[] array;
    private List<String> list;
    private Set<String> set;
    private Map<String,String> map;
    private Properties properties;
​
    //setter....方法省略
    
    public void save() {
        System.out.println("book dao save ...");
    }
}
数组:
<property name="array">
    <array>
        <value>100</value>
        <value>200</value>
        <value>300</value>
    </array>
</property>
set,list一次类推......
map:
<property name="map">
    <map>
        <entry key="country" value="china"/>
        <entry key="province" value="henan"/>
        <entry key="city" value="kaifeng"/>
    </map>
</property>
properties:
<property name="properties">
    <props>
        <prop key="country">china</prop>
        <prop key="province">henan</prop>
        <prop key="city">kaifeng</prop>
    </props>
</property>
​
注:property标签表示setter方式注入,构造方式注入constructor-arg标签内部也可以写<array>、<list>、<set>、<map>、<props>标签

1.3IOC&DI管理第三方bean

加载druid:
<!--管理DruidDataSource对象-->
<bean class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/spring_db"/>
    <property name="username" value="root"/>
    <property name="password" value="root"/>
</bean>
​
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource = (DataSource) ctx.getBean("dataSource");
System.out.println(dataSource);
​
xml读取外部配置文件:
1.开启context命名空间
<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">
</beans>
2.添加context标签:
<context:property-placeholder location="jdbc.properties"/>
3.通过${key}读取数据:
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${jdbc.driver}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>
​
注:system-properties-mode="NEVER"关闭系统加环境变量
<context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/>
​
读取多个配置文件:
<!--方式一 -->
<context:property-placeholder location="jdbc.properties,jdbc2.properties"/>
<!--方式二-->
<context:property-placeholder location="*.properties"/>
<!--方式三 -->
<context:property-placeholder location="classpath:*.properties"/>
<!--方式四-->
<context:property-placeholder location="classpath*:*.properties"/>

1.4核心容器

  • 使用BeanFactory创建的容器是延迟加载

  • 使用ApplicationContext创建的容器是立即加载

获取Bean的三种方式

  • getBean("名称"):需要类型转换

  • getBean("名称",类型.class):多了一个参数

  • getBean(类型.class):容器中不能有多个该类的bean对象

1.5使用注解开发bean

1.使用注解定义bean:

@Component("bookDao")
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ..." );
    }
}
​
//扫描注解
<context:component-scan base-package="com.itheima"/>

2.使用配置类删除配置文件:

@Configuration
@ComponentScan({"com.example.dao","com.example.service"}) //扫描bean
@Import({JdbcConfig.class}) //使用import注解手动导入需要加载的配置类
@PropertySource({"application.properties"}) //扫描配置问价
public class SpringConfig {
}
​
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
BookService bookServiceImpl = applicationContext.getBean("bookServiceImpl", BookService.class);
bookServiceImpl.save();
applicationContext.close();

3.使用注解开发bean的生命周期:

//bean的作用范围
@Scope("prototype")
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ...");
    }
}
​
//bean的初始化和销毁
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ...");
    }
    @PostConstruct //在构造方法之后执行,替换 init-method
    public void init() {
        System.out.println("init ...");
    }
    @PreDestroy //在销毁方法之前执行,替换 destroy-method
    public void destroy() {
        System.out.println("destroy ...");
    }
}

4.使用注解进行依赖注入:

@Autowired
@Qualifier("bookDao1") //多个同类型bean,则根据名称注入
private BookDao bookDao
//一般适用于读取配置文件属性
@Value("${name}")
private String name;
​
@PropertySource("jdbc.properties")
public class SpringConfig {
}

5.使用注解管理第三方bean:

@Configuration
public class JdbcConfig {
    //读取配置文件注入
    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;
    @Value("${spring.datasource.url}")
    private String url;
    @Value("${spring.datasource.password}")
    private String password;
    @Value("${spring.datasource.username}")
    private String username;
​
    @Bean
    public DataSource GetDataSource(BookDao bookDao){
        //构建DataSource对象的时候,需要用到BookDao对象
        System.out.println(bookDao);
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driverClassName);
        ds.setUrl(url);
        ds.setPassword(password);
        ds.setUsername(username);
        return ds;
    }
}
​
@Configuration
@ComponentScan("com.itheima.dao")
@Import({JdbcConfig.class}) //使用import注解手动导入需要加载的配置类
@PropertySource({"application.properties"})
public class SpringConfig {
}
​
//第三方bean
AnnotationConfigApplicationContext ctx1 = new AnnotationConfigApplicationContext(JdbcConfig.class);
DataSource DataSource = ctx1.getBean(DataSource.class);
System.out.println(DataSource);

1.6AOP

AOP在JavaWeb阶段已经详细学过,此次只增加其他内容

使用AOP获取数据参数异常:

1.获取参数:
@Around("pt()")
public Object around(ProceedingJoinPoint pjp)throws Throwable {
        Object[] args = pjp.getArgs();
        System.out.println(Arrays.toString(args));
        args[0] = 666;
        Object ret = pjp.proceed(args);
        return ret;
}
2.获取返回值:
@AfterReturning(value = "pt()",returning = "ret")
public void afterReturning(Object ret) {
    System.out.println("afterReturning advice ..."+ret);
}
3. 获取异常:
@AfterThrowing(value = "pt()",throwing = "t")
public void afterThrowing(Throwable t) {
    System.out.println("afterThrowing advice ..."+t);
}

1.7事务

开启事务:
1.添加注解:
@Transactional
public void transfer(String out,String in ,Double money) {
    accountDao.outMoney(out,money);
    int i = 1/0;
    accountDao.inMoney(in,money);
}
2.配置事务管理器:
//配置事务管理器,mybatis使用的是jdbc事务
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
    DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
    transactionManager.setDataSource(dataSource);
    return transactionManager;
}
3.开启事务驱动:
@EnableTransactionManagement
public class SpringConfig {
}

事务角色:

事务属性:

  • timeout:设置超时时间单位秒,在多长时间之内事务没有提交成功就自动回滚,-1表示不设置超时时间。

  • rollbackFor:当出现指定异常进行事务回滚

Spring的事务只会对Error异常RuntimeException异常及其子类进行事务回顾

指定事务回滚:@Transactional(rollbackFor = {IOException.class})

  • noRollbackFor:当出现指定异常不进行事务回滚

事务的传播行为:

@Autowired
private LogDao logDao;
​
//propagation设置事务属性:传播行为设置为当前操作需要新事务
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void log(String out,String in,Double money ) {
    logDao.log("转账操作由"+out+"到"+in+",金额:"+money);
}
//此时不管事务1和事务2是否回滚,日志事务会一直执行下去
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值