:スプリングIOCとAOPは、二つの点IOCのコアである制御の反転 AOP:アスペクト指向プログラミング
IOCは、我々はもはや必要に手動でなく、Springコンテナによって新しいインスタンスを取得するようにSPINGコンテナにクラス登録を定義することです。呼び出されたオブジェクトは、コンストラクタによってフォームセットのオブジェクト()メソッドをインスタンス化またはながらバネコンテナは、オブジェクトの発信者を作成する(プロファイルが注釈構成を記述することなく直接使用することができる)プロファイルに基づいて説明する注入オブジェクトを呼び出し側にそれら。
IOCコンテナを通じ、開発者はオブジェクトが作成されているかに焦点を当てる必要はありませんし、新しいクラスが非常に簡単に使用することもあり、唯一の設定ファイルを変更する必要があります。
例指向プログラミングAOPは、開発者がビジネスロジックのオリジナルモデルの変更が動的にログ、セキュリティや例外処理を向上させることができるではないかもしれません。
ただ、特定のポイント(カット)の前と後のいくつかの新機能を追加するために、元のソースコードを変更しない春とアスペクト指向プログラミングも、この機能AOPファーストをサポートしている我々は、設定ファイルに関連する構成をインポートする必要があり、我々はAOPを実現する3つの方法があります。
適切なインタフェースを実装する最初の書き込み実装クラス
public class AfterLog implements AfterReturningAdvice {
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
System.out.println("已经执行了" + method.getName() + " 方法,结果为 " + o);
}
}
public class BeforeLog implements MethodBeforeAdvice {
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("在" + o.getClass().getName() + "执行了" + method.getName() + "方法");
}
}
MethodBeforeAdviceインタフェースは、彼が名前を持ち、メソッド名は、いくつかの種類のパラメータのというように取得することができます前に、エントリポイント関数が実行さを表します。AfterReturningAdviceインタフェースは、エントリポイント関数は(彼はメソッドの開始点が唯一のエントリポイントの後に、それは得ることができ、戻り値を有していてもよく行われているため)彼の後MethodBeforeAdvice値より1つの引数がリターンを表して行われる表します。
その後、クラスと、彼はエントリポイントの前または後に行うことができるように、設定ファイルに彼の変換のいずれかを記述します。第二の方法
public class DiyPointCut {
public void before(){
System.out.println("+++++++++++before+++++++++++++++");
}
public void after(){
System.out.println("+++++++++++after+++++++++++++++");
}
}
彼は二つのインターフェースが、に比べて、プロファイルの変換によりことを認識していなかったので、第二の方法と第一の方法は、より便利で、彼は彼のすべての関数の2つのインターフェイスが非常に限られていることを認識していなかったものですが、彼は同じようにはできません第一の方法は、エントリポイント情報に対応する数として求めることができます
第三の方法は、構成によって注釈及び第二のアプローチと同様に、本明細書に記載の多くのない機能です。
次のようにコンフィギュレーションファイルは、次のとおりです。
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="afterlog" class="com.Jee.log.AfterLog"/>
<bean id="beforelog" class="com.Jee.log.BeforeLog"/>
<bean id="userserviceimpl" class="com.Jee.service.UserServiceImpl"/>
<!-- <aop:config>-->
<!-- <!–第一种方式 : 切入点–>-->
<!-- <aop:pointcut id="pointcut" expression="execution(* com.Jee.service.UserServiceImpl.*(..))"/>-->
<!-- <!–执行环绕增加–>-->
<!-- <aop:advisor advice-ref="afterlog" pointcut-ref="pointcut"/>-->
<!-- <aop:advisor advice-ref="beforelog" pointcut-ref="pointcut"/>-->
<!-- </aop:config>-->
<bean id="diy" class="com.Jee.diy.DiyPointCut"/>
<aop:config>
<!--第二种方式 : 定义切面-->
<aop:aspect ref="diy">
<!--定义切入点-->
<aop:pointcut id="point" expression="execution(* com.Jee.service.UserServiceImpl.*(..))"/>
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
</aop:aspect>
</aop:config>
</beans>
AOP:コンフィグタグは依存相関AOPを定義する必要はない以下AOPある:ポイントカットは、その発現のエントリポイントを指すが、この特定のエントリポイント位置(の表現である)が、この文言の固定された実行によって表される
実行(* COM .Jee.service.UserServiceImpl。(...))でこの式の任意の意味は、カテゴリcom.Jee.serviceパッケージの下のいずれかの方法UserServiceImpl位置をポイントカット。
コントロールのIOC反転
適用できない場合は、クラスを定義するには、設定ファイルに直接コメント
<?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表示这个实例的名字 class表示他的全类名
property标签中的name代表类中的属性名 value表示值
但是 这样的话 value只能表示一些基本数据类型 那些复杂的例如 数组 集合 map等数据类型无法表示
这个时候我们就需要使用其他的一些标签了
<bean id="address" class="com.Jee.entity.Address">
<property name="city" value="武汉"/>
<property name="stress" value="人民医院"/>
</bean>
<bean id="student" class="com.Jee.entity.Student">
<property name="id" value="1"/>
<property name="name">
<null/>
</property>
//ref表示一个引用 如果你定义好了一个属性 你直接可以使用ref来引用你定义好的id
<property name="address" ref="address"/>
<property name="books">
//如果类型是数组 就使用array标签表示 用value设置数组中的值
<array>
<value>"算法导论"</value>
<value>"Java核心"</value>
<value>"计算机组成原理"</value>
<value>"数据库基础"</value>
</array>
</property>
<property name="cards">
//如果是map类型的话 使用map标签 用过entry表示数据 entry中有key和value
<map>
<entry key="校园卡" value="这是一张校园卡"/>
<entry key="门禁卡" value="这是一张门禁卡"/>
<entry key="水卡" value="这是一张水卡"/>
</map>
</property>
<property name="games">
//如果数据类型是set类型 使用set标签 用value标签表示set中的值
<set>
<value>LOL</value>
<value>BOB</value>
<value>FOF</value>
</set>
</property>
<property name="hobbys">
//如果数据类型是集合 就使用list标签 value标签表示list中的值
<list>
<value>唱</value>
<value>跳</value>
<value>Rap</value>
<value>篮球</value>
</list>
</property>
<property name="info">
//类型是prop的话 使用这种(虽然我也不知道prop是什么类型)
<props>
<prop key="driver">driver</prop>
<prop key="url">url</prop>
<prop key="username">username</prop>
<prop key="password">password</prop>
</props>
</property>
</bean>
</beans>
使用注釈は春のすべての注釈をスキャンする指定した行のパッケージの前に直接スキャン開かれたファイルの注釈内の構成ファイル内のクラス属性を定義する必要はありません自動的に対応するパケットをスキャンします
<?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/>
<!--扫描这个包下的所有注解-->
<context:component-scan base-package="com.Jee.entity"/>
<!-- <bean id="dog111" class="com.Jee.entity.Dog">-->
<!-- <property name="name" value="狮子汪"/>-->
<!-- </bean>-->
<!-- <bean id="cat222" class="com.Jee.entity.Cat">-->
<!-- <property name="name" value="喵尔摩斯"/>-->
<!-- </bean>-->
<!-- <bean id="person" class="com.Jee.entity.Person">-->
<!-- <property name="name" value="天人"/>-->
<!-- </bean>-->
</beans>
对应的类
//@Component注解代表这个类是一个组件 可以被@Autowired自动导入
@Component
public class Dog {
//@Value注解定义在字段上 表示这个字段的值
@Value("狮子汪")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
'}';
}
public void speak(){
System.out.println("wow wow wow ");
}
}
@Component
public class Person {
private String name;
//@AutoWired注解 表示自动导入 像这个例子 Cat类和Dog类 如果我们已经把他们添加到了Spring容器中 我们就可以使用@AutoWired实现自动导入 而不需要手动配置
@Autowired
private Cat cat;
@Autowired
private Dog dog;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", cat=" + cat +
", dog=" + dog +
'}';
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
}
我々は唯一の行に設定クラスを定義する必要があり、構成ファイルを使用して行く必要がありませんので、私たちのクラス定義を生成するには、設定クラスを使用します
User类
@Component
public class User {
@Value("1")
private int id;
@Value("魔法猫咪")
private String name;
private String[] games;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getGames() {
return games;
}
public void setGames(String[] games) {
this.games = games;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", games=" + Arrays.toString(games) +
'}';
}
}
以上两种都是使用配置文件来注册相应的类的 要拿到我们定义好的类 需要使用如下的方法
public class MyTest {
//这个一个junit测试类
@Test
public void test(){
//使用new ClassPathXmlApplicationContext这个类 参数是我们配置文件的名称
//可以使用getBean来获得我们注册的类的实例 参数是我们bean标签中的id
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Person person = (Person) context.getBean("person");
System.out.println(person);
System.out.println(person.getCat());
person.getCat().speak();
System.out.println(person.getDog());
person.getDog().speak();
}
}
配置类(不需要使用配置文件了 直接定义这个类就行)
//@Configuration注解表示这个类是一个配置类
@Configuration
//@Import注解可以导入其他的配置类
@Import(JeeConfig2.class)
public class JeeConfig {
//@Bean注解表示这个方法是一个可以返回一个实例的方法 从而可以在ApplicationContext类中使用
@Bean
public User getUser(){
return new User();
}
@Bean
public Address address(){
return new Address();
}
}
使用配置类,我们获得实例的方法同上述两种有一点细微的区别
public class MyTest {
@Test
public void test(){
//new的是AnnotationConfigApplicationContext这个类 参数变成了我们定义的配置类
ApplicationContext context = new AnnotationConfigApplicationContext(JeeConfig.class);
User getUser = (User) context.getBean("getUser");
System.out.println(getUser);
System.out.println("1111111111111");
System.out.println((Address)context.getBean("address"));
}
}
私たちの事業の総務は、そのセキュリティを保証するためにトランザクションを使用する必要があり、データベースの操作についての不注意ではないことが非常に重要である
業務ACIDの4つの特徴
1、アトミック(不可分)
アトミックは、すべての成功のいずれか含まトランザクション内のすべての操作を指し、またはすべてが失敗します操作は、データベースへの影響を持つことができません失敗した場合、ロールバック、トランザクションが成功した場合のオペレータは、それが完全にデータベースに適用されなければなりません。
2.一貫性(一貫性)
トランザクションは、トランザクションの実行と実装が一貫性のある状態でなければなりません前と後と言うことです別の一貫性のある状態、1つの一貫した状態からデータベースを変換する必要があることを一貫手段。ユーザーAとユーザーBのお金の両方が1000の合計まで追加した場合、その後、何のトランザクションの終了後にお金が2人のユーザーまで追加、AとBの間の転送は、複数のアカウントを有効にする方法は問題でなければならないはず1000年には、これはトランザクションの一貫性です。
図3に示すように、分離(単離)
単離する際のユーザの複数のそのようなテーブルを用いて同時に動作する場合、各ユーザトランザクションオープン用のデータベースは、動作は、他のトランザクションによる同時トランザクションの複数の妨害されないようなデータベースへの同時アクセス、互いから部屋を分離します。データベースの分離レベルを数多く提供してトランザクション分離については、後でに導入されます。
図4は、永続性(耐久性)
トランザクションがコミットされると、データベース内のデータを変更することを永続手段は永久的な、データベース・システムの場合にも、失われることはありませんトランザクションのコミット操作の失敗を経験しています。たとえば、私たちは、JDBCデータベース操作を使用するプロンプトが表示されるまで、私たちは、プログラムの実行を完了すると、トランザクションがコミットする方法である後に、ユーザーはトランザクションが完了するよう求めている、あなたは、トランザクションを識別することができ、この時点では、データベースに問題があっても、正常に提出されました、それは必要があります私たちのビジネスの完全な実装を完了します。そうでなければ、私たちは、取引の迅速な完了を確認しながら、それは重大なエラーになりますが、データベースがあるため、トランザクションを実行するには失敗ではありません。これは許可されていません。
春には、トランザクションコードを使用して、コンフィギュレーションファイルに設定する必要がありますにパッケージ名を変更するには、ほとんど死んのみ必要です
<!--配置声明式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<constructor-arg ref="dataSource" />
</bean>
<!--结合AOP实现事务的植入-->
<!--配置事务通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--给哪些方法配置事务-->
<tx:attributes>
<tx:method name="addUser"/>
<tx:method name="deleteUser"/>
<tx:method name="query"/>
<tx:method name="update"/>
</tx:attributes>
</tx:advice>
<!--配置事务切入-->
<aop:config>
<!--配置切入点-->
<aop:pointcut id="txPointCut" expression="execution(* com.Jee.mapper.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>